DHTML Lab: Hierarchical Menus Version 3 | 8
Hierarchical Menus: Version 3
| |||
Click the link above to reveal menu. Click anywhere on the page to hide menu. Parameters used for the menus on this page: menuVersion = 3; menuWidth = 120; childOffset = 5; perCentOver = 30; secondsVisible = 1; fntCol = "black"; fntSiz = "10"; fntBold = true; fntItal = false; fntFam = "serif"; backCol = "#00cc00"; overCol = "#008800"; overFnt = "red"; borWid = 2; borCol = "darkgreen"; borSty = "solid"; itemPad = 3; imgSrc = "tri.gif"; imgSiz = 10; separator = 1; separatorCol = "darkgreen"; isFrames = false; keepHilite = true; NSfontOver = false; clickStart = true; clickKill = true; showVisited = ""; Background Reading: itemOver(): itemOut(): In script listings, cross-browser code is blue, Navigator-specific code is red, and Explorer code is green. The [cc] symbol denotes code continuation. The code is part of the preceding line. It is placed on a new line for column formatting considerations only. |
The two features introduced in version 3 that help alter the itemOver() and itemOut() functions so drastically are:
Item mouseoveritemOver() now looks like this: 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(); } } this.container.currentItem = this; if (this.container.hasChildVisible) { this.container.hideChildren(this); } if (this.hasMore) { horOffset = (isRight) ? [cc] (this.container.childOverlap - this.container.menuWidth) : [cc] (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 + [cc] 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); } } The first group of statements are executed only if keepHilite is true: if (keepHilite) { The second statement modifies the condition further. It checks the value of the container menu's currentItem property. Recall that the currentItem property of all menus was set to null in menuSetup(). It will still be null if the item-in-question is the first item we have moused over. If currentItem has no value (i.e. it is null), the second part of the && logical operator is not executed. If currentItem has a value then we check to see if it is equal to the item we are working with. If it is not the same, then the we move on to execute the statements: if (this.container.currentItem && this.container.currentItem != this) { In plain English, the above line reads: "If the item the mouse is over is not the first item moused over nor is it the last item moused over in this menu, then execute the contained statements." We thus avoid unnecessary flicker that would occur if we de-highlighted an item that was then highlighted. Thus, if the item passes the conditional statements, it means that a different item in the menu is the "current item," is presently highlighted, and needs de-highlighting. For Navigator, we change the curent item's background color, as before: if (NS4) { this.container.currentItem.bgColor = this.container.menuBGColor; If NSfontover is true, we must also change the font color. Since the string we will write to the element contains a link, we make sure that it renders in the correct color, by setting the linkColor property of the item element's document. We then write the string stored in the item's htmStr property. Recall that this is the standard non-highlighted string. if (NSfontOver) { with (this.container.currentItem.document) { linkColor = this.container.menuFontColor; write(this.container.currentItem.htmStr); close(); } } } For Explorer users, we simple assign the relevant tree-specific values to the backgroundColor and color properties of the item's style: else { with (this.container.currentItem.style) { backgroundColor = this.container.menuBGColor; color = this.container.menuFontColor; } } } } Now, we have de-highlighted any already-highlighted item, if keepHilite is true. At this stage there are no highlighted items. We proceed to highlight the item the mouse is over. The statements are as in other versions, only with tree-specific values. For Navigator users, the item's htmStrOver string is written to the item, if NSfontOver is true. 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(); } } The "old" item has been possibly de-highlighted and the new one highlighted. This new item is assigned to the menu's currentItem property, since it is now the "current item." this.container.currentItem = this; As before, any visible child menu, opened by the "old" item, is hidden: if (this.container.hasChildVisible) { this.container.hideChildren(this); } The final group of statements opens the child menu of the item, if one exists, with two modifications from version 2:
if (this.hasMore) { horOffset = (isRight) ? [cc] (this.container.childOverlap - this.container.menuWidth) : [cc] (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 + [cc] this.container.style.pixelTop + childOffset; } itemOver ends with the same five statements as in version 2. The child menu is positioned, properties are set and it is made visible: this.child.moveTo(this.childX,this.childY); this.child.keepInWindow(); this.container.hasChildVisible = true; this.container.visibleChild = this.child; this.child.showIt(true); } } Item mouseoutThe itemOut() function is exteremely straightforward. It only changes an item's highlight (de-highlights) if keepHilite is false. It also checks NSfontOver and writes to the item to change the font color. function itemOut() { if (IE4) { theEvent = menuLoc.event; if (theEvent.srcElement.contains(theEvent.toElement) || (theEvent.fromElement.tagName=="IMG" && [cc] theEvent.toElement.contains(theEvent.fromElement))) return; if (!keepHilite) { this.style.backgroundColor = this.container.menuBGColor; this.style.color = this.container.menuFontColor; } } else { if (!keepHilite) { this.bgColor = this.container.menuBGColor; if (NSfontOver) { with (this.document) { linkColor = this.container.menuFontColor; write(this.htmStr); close(); } } } if (!isOverMenu && !clickKill) { allTimer = setTimeout("currentMenu.hideTree()",10); } } } As in version 2, when the item is moused out in Navigator and we are no longer over any menu (!isOverMenu), the allTimer timer is set to hide the menu tree. The difference in this version is that allTimer is not set if clickKill is true. In that case, we wait for the user to click outside the menus to hide them. On the next page, we'll look at the functions related to menu positioning and display. |
Produced by Peter Belesis and
All Rights Reserved. Legal Notices.Created: Sept. 03, 1998
Revised: Sept. 03, 1998
URL: https://www.webreference.com/dhtml/column21/hier3Itover.html