Flylib.com

Books Software

 
 
 

10.2 Keeping a Page Out of the Browser History

10.2 Keeping a Page Out of the Browser History

NN 3, IE 4

10.2.1 Problem

You want to remove the current page from the browser history so that the Back button does not take the user back to the current page after a script navigates to some other page.

10.2.2 Solution

Navigate to the next page via the location.replace( ) method:

location.replace("http://www.megacorp.com/indexDHTML.html");

10.2.3 Discussion

The capability of keeping a page out of the browser's history can come in handy when your site contains a page that include automatic forwarding under script control. Recipe 5.10 is a typical situation that benefits from keeping a temporary page out of the history. If the user reaches the real home page, a press of the browser's Back button normally brings the user back to the temporary page, and the user is essentially trapped in an infinite loop from which escape can only occur by going forward.

You can also use this technique if you do not want a user to come back to a form after submitting it. But in this case, you must assemble the form data yourself, appending it to the URL string passed with the replace( ) method. The page returned from your CGI program replaces the form page in the browser history. Be aware, however, that this works only for form submissions that can be accomplished with the GET method, rather than the POST method. Invoking the location.replace( ) method causes the browser to request a page through a GET method just like a regular web page.

10.2.4 See Also

Recipe 5.10 for a likely scenario for using location.replace( ) ; Recipe 10.6 to see how to assemble form data as part of a URL.

10.3 Using a select Element for Navigation

NN 2, IE 3

10.3.1 Problem

You want users to choose a destination from a pop-up list originating from a <select> tag.

10.3.2 Solution

You have a few scripting possibilities for this solution, depending on your design and scripting style, but they all rely on the select element having been outfitted with option elements containing the URL for each destination. You can display any text you like that is visible in the list, but assign the URL for each item to the value attribute of each option :

<select name="chooser" id="chooser">
    <option value="">Choose a Destination:</option>
    <option value="http://www.megacorp.com/index.html">Home</option>
    <option value="http://www.megacorp.com/products/index.html">Products</option>
    <option value="http://www.megacorp.com/support/index.html">Support</option>
    <option value="http://www.megacorp.com/contact.html">Contact Us</option>
</select>

Some event must trigger the navigation action. The most backward-compatible approach is to locate a clickable button or "Go" icon next to the select element. The onclick event handler of that button or link- surrounded image invokes a function that reads the selected option's value property:

function navigate( ) {
    var choice = document.forms[0].chooser;
    var url = choice.options[choice.selectedIndex].value;
    if (url) {
        location.href = url;
    }
}

Perhaps more convenient for users is to trigger the navigation by making the choice from the list, in which case, you can create a generic (reusable) function that receives as an argument a reference to a select element:

function navigate(choice) {
    var url = choice.options[choice.selectedIndex].value;
    if (url) {
        location.href = url;
    }
}

The event handler in the select element should be as follows :

<select name="chooser" id="chooser" onchange="navigate(this)">...</select>

10.3.3 Discussion

The myriad of ways to translate a select element's choice into a navigation command depend primarily on the browser versions you need to support and your coding style, particularly with respect to event processing. For example, in IE 4 or later and NN 6 or later, you can access the value property of the chosen option by simply retrieving the value property of the select element directly. This cuts down on all the options array referencing shown in the Solution. On the other hand, if you wish to bind the onchange (or other) event to the select element through other means, the event handler function cannot receive a reference to the select element as an argument. Instead, the function has to derive that information from the event object in a way that applies to both the IE and NN event models:

function navigate(evt) {
   evt = (evt) ? evt : ((event) ? event : null);
   if (evt) {
      var elem = (evt.target) ? evt.target : ((evt.srcElement) ? 
          evt.srcElement : null);
      if (elem && elem.tagName.toLowerCase( ) =  = "select" && elem.value) {
         location.href = elem.value;
      }
   }
}

You can then bind the event handler within the tag:

<select name="chooser" id="chooser" onchange="navigate(event)">...</select>

Or in a script statement that executes after the page loads:

document.getElementById("chooser").onchange = navigate;

The scheme presented thus far has a significant flaw, however. If the user navigates from the current page to a choice in the select element and then returns to this page via the Back button, most browsers display the page just as it was the instant it unloaded—with the last choice preselected. The problem is that if the user wants to make the same selection again, the select element will not fire an onchange event (in most browsers). In other words, the user won't be able to duplicate the choice a second time without first making some other choice. You might think to bind any mouse- related events to trigger the navigation, but this is fraught with peril, because users can mouse down, mouse up, and click on a select element just to look through it, or (in some operating systems) keep a sticky list showing to view the list. Thus, mouse events are not suitable substitutes.

To force the user to make a selection that fires the onchange event, script the page to restore the select element (or perhaps all form controls) to its default state either via the onload or onunload event for the document or window objects. Either invoke the reset( ) method of the containing form element object, or set the selectedIndex property of the select element to zero. Notice that the select element shown in the Solution contains an initial choice that has no value—just a text label with instructions. All of the navigation event handler functions shown here assign a value to the location.href property only if there is, indeed, a value (other than an empty string) associated with the selected option.

You may wonder why, with the efficiency of the onchange event handler, a designer would include a "Go" button next to a select element. There are two primary reasons. First, some user interface designers don't like the idea of a select element triggering as drastic an action as navigating to another page. In other words, they intentionally separate the actions of choosing and going. Second, a historical precedent was set in Navigator 2, in which the onchange event handler for select elements was broken in the Windows versions of that browser (the element had to lose focus before the event would fire). To get a select element to do anything with a chosen item, the designer had to include a clickable element to initiate the going part (even if it was a dead element to get the focus out of the select element). How much each of these reasons influences today's designs is hard to say. If I want to make a page that provides select list navigation, yet can also work with nonscriptable browsers, I would include a "Go" button, but use scripted feature detection and style sheets to hide the button in scriptable, CSS-capable browsers.

10.3.4 See Also

Recipe 7.2 and Recipe 7.3 for controlling navigation of other frames ; Recipe 14.1 for ideas about using scripts to add content to a page dynamically during page loading.