DHTML Lab - dhtmlab.com - Hierarchical Menus Ver. 3 - Addendum V (v3.05) | 4 | WebReference

DHTML Lab - dhtmlab.com - Hierarchical Menus Ver. 3 - Addendum V (v3.05) | 4

Logo

Hierarchical Menus Ver. 3 - Addendum V (v3.05)
status bar URL display


As we know, the menu item links are not created with the A tag. In fact, they are not links at all. Our script associates a URL or an action with an item click (IE4) or mouseup (NS4) and navigates to the URL or executes the action when the event is received. Granted, in Navigator, we do insert A tags but only to create the hand cursor, not to navigate with.

Consequently, the status bar does not display a URL upon item mouseover. This is a little disconcerting for some users, who expect this behavior.

We need to modify our script in three places. The first and second changes, in itemOver() and menuOut() affect the behavior of both browsers. The third, in itemSetup() affects only Navigator.

itemOver()

The itemOver() function executes whenever the user mouses over an item, so it's the logical place to include a statement that displays a string in the status bar. The string to be displayed is the item object's linkText property. The "window" object, to which the status property belongs, is represented by our menuLoc object:

menuLoc.status = this.linkText;

We include the statement to be executed in a cross-browser part of our function:

function itemOver(){
  if (keepHilite) {
    if (this.container.currentItem && this.container.currentItem != this) {
      if (NS4) {
        this.container.currentItem.bgColor = this.container.menuBGColor;
        if (NSfontOver) {
          with (this.container.currentItem.document) {
            linkColor = this.container.menuFontColor;
            write(this.container.currentItem.htmStr)
            close();
          }
        }
      }
      else {
        with (this.container.currentItem.style) {
          backgroundColor = this.container.menuBGColor;
          color = this.container.menuFontColor;
        }
      }
    }
  }
  if (IE4) {
    theEvent = menuLoc.event;
    if (theEvent.srcElement.tagName == "IMG") return;
    this.style.backgroundColor = this.container.menuBGOver;
    this.style.color = this.container.menuFontOver;
  }
  else {
    this.bgColor = this.container.menuBGOver;
    if (NSfontOver) {
      this.document.write(this.htmStrOver);
      this.document.close();
    }
  }

// 3.05: add next line for status bar display when mousing over item:
  menuLoc.status = this.linkText;
  this.container.currentItem = this;
  if (this.container.hasChildVisible) {
    this.container.hideChildren(this);
  }
  if (this.hasMore) {
    horOffset = (isRight) ? (this.container.childOverlap - this.container.menuWidth)
     : (this.container.menuWidth - this.container.childOverlap);
    if (NS4) {
      this.childX = this.container.left + horOffset;
      this.childY = this.pageY + childOffset;
    }
    else {
      this.childX = this.container.style.pixelLeft + horOffset;
      this.childY = this.offsetTop + this.container.style.pixelTop + childOffset;
    }
    this.child.moveTo(this.childX,this.childY);
    this.child.keepInWindow();
    this.container.hasChildVisible = true;
    this.container.visibleChild = this.child;
    this.child.showIt(true);
  }
}

menuOut()

We could cancel the status display on every item mouseout, but a more elegant method would be to cancel the display only when we leave the complete menu. While we are over the menu, we are always over an item, and we want the appropriate status display. When we mouseout of an item, we may be mousing over another item, which sets the status again, anyway. So a cancellation on item mouseout is just extra, unecessary, work for our script.

We, therefore, include one line in menuOut():

function menuOut() {
  if (IE4) {
    theEvent = menuLoc.event;
    if (theEvent.srcElement.contains(theEvent.toElement)) return;
  }
  this.isOn = false;
  isOverMenu = false;

// 3.05: added next line to cancel status bar display when mousing out of menu:
  menuLoc.status = "";
  if (!clickKill) allTimer = setTimeout("currentMenu.hideTree()",10);  
}

itemSetup()

All links automatically display the HREF value in the status bar when moused over. When moused out, the previous status display is restored. Our HREF value is always the dummy "javascript:void(0)", which will overwrite the itemOver() status display set above. We must, therefore, instruct our script to display the item's linkText value, instead of the default.

The dummy link in every item is the first and only link in the item. It is reflected into JavaScript as the first element in the item layer's document.links array. That is, as this.document.links[0]. We can set the onmouseover behavior dynamically with this syntax:

this.document.links[0].onmouseover = functionName;

Unfortunately, we cannot assign a function name to the onmouseover handler, in our usual way, because there is one piece of information that the function will not be able to easily retrieve later: the linkText value. The only time when we have this bit of information handy is now, during the assignment statements, in itemSetup().

We, therefore create a string to be evaluated that includes the function as a literal assignment, and the proper string value for the status display:

if (this.linkText)
    eval("this.document.links[0].onmouseover = function(){menuLoc.status='"+ this.linkText +"';return true}");

Notice that the statement is only executed if linkText has a value, which is also the only time that the link is created.

The complete itemSetup(), therefore, incorporating the previous fix discussed, now looks like this:

function itemSetup(whichItem,whichArray) {
  this.onmouseover = itemOver;
  this.onmouseout = itemOut;
  this.container = (NS4) ? this.parentLayer : this.offsetParent;
  arrayPointer = (this.container.hasParent) ? (whichItem-1)*3 : ((whichItem-1)*3)+9;
  this.dispText = whichArray[arrayPointer];
  this.linkText = whichArray[arrayPointer + 1];
  this.hasMore = whichArray[arrayPointer + 2];
  if (IE4 && this.hasMore) {
// 3.05: omit the next line:
//    this.child = eval("elMenu" + this.id.substr(this.id.indexOf("_")-1));
// 3.05: replace with this line:
    this.child = eval("elMenu" + this.id.substr(4));
    this.child.parentMenu = this.container;
    this.child.parentItem = this;
  }
  if (this.linkText) {
    if (NS4) {
      this.captureEvents(Event.MOUSEUP)
      this.onmouseup = linkIt;
    }
    else {
      this.onclick = linkIt;
      this.style.cursor = "hand";
    }
  }
  if (NS4) {
    htmStr = this.dispText;
     this.document.tags.A.textDecoration = "none";
    if (fntBold) htmStr = htmStr.bold();
    if (fntItal) htmStr = htmStr.italics();
    htmStr = "<FONT FACE=" + fntFam + " POINT-SIZE=" + fntSiz + ">" + htmStr+ "</FONT>";
    
    if (this.linkText) {
      with (this.document) {
        linkColor = this.container.menuFontColor;
        alinkColor = this.container.menuFontColor;
        vlinkColor = (showVisited) ? showVisited : this.container.menuFontColor;
      }
      htmStrOver = htmStr.fontcolor(this.container.menuFontOver).link("javascript:void(0)");
      htmStr = htmStr.link("javascript:void(0)");
    }
    else {
      htmStrOver = htmStr.fontcolor(this.container.menuFontOver);
      htmStr = htmStr.fontcolor(this.container.menuFontColor);
    }
    
    this.htmStr = (this.hasMore) ? imgStr + htmStr : spStr + htmStr;
    this.htmStrOver = (this.hasMore) ? imgStr + htmStrOver : spStr + htmStrOver;    
    
    this.document.write(this.htmStr);
    this.document.close();

// 3.05: added next 2 lines for status bar display when mousing over link part of item:
    if (this.linkText)
      eval("this.document.links[0].onmouseover = function(){menuLoc.status='"+ this.linkText +"';return true}");
    this.visibility = "inherit";
    this.bgColor = this.container.menuBGColor;
    if (whichItem == 1) {
      this.top = borWid + itemPad;
    }
    else {
      this.top = this.prevItem.top + this.prevItem.clip.height + separator;
    }
    this.left = borWid + itemPad;
    this.clip.top = this.clip.left = -itemPad;
    this.clip.bottom += itemPad;
    this.clip.right = this.container.menuWidth-(borWid*2)-itemPad;    
  }
  else {
    with (this.style) {
      padding = itemPad;
      if (isRight && !this.hasMore) paddingLeft = parseInt(padding)+imgSiz;
      color = this.container.menuFontColor;
      fontSize = fntSiz + "pt";
      fontWeight = (fntBold) ? "bold" : "normal";
      fontStyle =  (fntItal) ? "italic" : "normal";
      fontFamily = fntFam;
    
      borderBottomWidth = separator + "px";
      borderBottomColor = this.container.menuSeparatorCol;
      borderBottomStyle = "solid";
      backgroundColor = this.container.menuBGColor;
    }
  }
}

Our new statement has been placed after the document.write() that creates the link. It is at this point that the document.links array includes our dummy link.

That's it for this release. On the next page, as usual, the complete hierMenus.js external file. Please upgrade to this new version.


Produced by Peter Belesis and

All Rights Reserved. Legal Notices.
Created: Jan 26, 1999
Revised: Jan 26, 1999

URL: http://www.webreference.com/dhtml/column21/addendum5/col21addV4.html