DHTML Lab - dhtmlab.com - Hierarchical Menus Ver. 3 - Addendum II (v3.02) | 3 | WebReference

DHTML Lab - dhtmlab.com - Hierarchical Menus Ver. 3 - Addendum II (v3.02) | 3


Logo

Hierarchical Menus Ver. 3 - Addendum II (v3.02)
improving an old bug fix and introducing a new one


Click the buttons above to view the behavior of the different versions in a new window.

The Problem

"(other items) work exactly as advertised, but the new window in item 1 is a bit over anxious. Basically, the main window loses all its info and is replaced by a blank window with nothing but '[object Window]' in the upper left corner. The script then opens 2 new windows, both of which contain the URL I'm looking for."

The menu item referred to above (item 1) contained a javascript: URL that opened a new window.

You will recall that we introduced the ability for menu items to link to non-http URLs in version 2.1. And the feature worked perfectly.

In version 3, after much reader request, we changed the menu item HTML to include actual <A HREF=> links, for Navigator, so that a "hand" cursor would appear upon user mouseover.

The relevant statements that create the link are:

function itemSetup() {
...
htmStrOver =
  htmStr.fontcolor(this.container.menuFontOver).link(this.linkText);
    htmStr = htmStr.link(this.linkText);
...
}

Notice that we assign the linkText property to be the HREF string for the A tag.

This might be a little confusing out of context, so lets reproduce, in static HTML, what the script creates dynamically. A menu with one item, if we hard-coded it, would have this HTML/script in its Navigator incarnation:

<LAYER ID="elMenu1" CLIP=100,24 BGCOLOR=black>
<LAYER ID="item1_1"
  LEFT=4 TOP=4 BGCOLOR=#EEEEEE CLIP=-3,-3,95,19
  onMouseOver="this.bgColor='pink'"
  onMouseOut="this.bgColor='#EEEEEE'">
      <A HREF="javascript:window.open('extFile.html')">Menu Item</A>
</LAYER>
</LAYER>
<SCRIPT LANGUAGE="JavaScript1.2">
  elMenu1 = document.layers["elMenu1"]
  item = elMenu1.document.layers["item1_1"];
  item.linkText = "javascript:window.open('extFile.html')"
  item.captureEvents(Event.MOUSEUP);
  item.onmouseup = linkIt;
  function linkIt() {
    if (this.linkText.indexOf("javascript")!=-1)
        {eval(this.linkText);return}
    menuLoc.location.href = this.linkText;
  }
</SCRIPT>

Now, the problem becomes apparent. We have linked to the javascript: URL twice. Once in the A tag, which surrounds the text within the item, and once for the complete item itself! If the user clicks on the text within the item, the javascript: URL is executed by the item itself, through the linkIt() function, then the event is passed down and executed again by the A tag. Since, in our example, the javascript: URL opens a new window, the new window is opened twice!

With standard http: URLs, this problem does not surface, since the item loads a new page and all further action is cancelled. The A tag never receives the event to duplicate the action. And this is why we didn't catch the problem when creating Version 3.

The Solution

The problem is easily overcome by ensuring that all clicks are handled by the item itself and not by the A tag. In fact, the A tag becomes a dummy tag, its sole purpose being to create a "hand" cursor for friendlier navigation. We accomplish this by giving all A tags in menu items a javascript:void(0) URL. This special JavaScript URL uses the void operator to evaluate an expression without returning a value. Since the expression to be evaluated is 0, nothing happens. A dummy HREF is created!

htmStrOver =
  htmStr.fontcolor(this.container.menuFontOver).link("javascript:void(0)");
htmStr = htmStr.link("javascript:void(0)");

We can add further mechanism to avoid the double-link, by adding a return false to the linkIt() function:

function linkIt() {
	if (this.linkText.indexOf("javascript")!=-1){
        eval(this.linkText);
        return true
    }
	menuLoc.location.href = this.linkText;
	return false;
}

In Navigator, if one return in a function has a value, then all returns must have values. In Explorer, a return without a value defaults to true. Since we have added a return false, our previous return is changed to return true.

On the next page, we reproduce the complete hierMenus.js external file. Please upgrade to this new version.


Produced by Peter Belesis and

All Rights Reserved. Legal Notices.
Created: Oct 04, 1998
Revised: Oct 04, 1998

URL: http://www.webreference.com/dhtml/column21/addendum2/col21addII3.html