DHTML Lab: Hierarchical Menus, I; The Complete Code 3/3
DHTML Hierarchical Menus, Part I
SPECIAL EDITION; the director's cut 3/3
The Hierarchical Menu Routines (hierMenus.js)
This file, along with the external array file, may be download in ZIP format
/*hierMenus.js * By Peter Belesis. v1.0 980220 * Copyright (c) 2001 Peter Belesis. All Rights Reserved. * Originally published and documented at https://www.dhtmlab.com/ * Available solely from INT Media Group. Incorporated under exclusive license. * Contact [email protected] for more information. */ semi = ";"; styleStr = "<STYLE TYPE='text/css'>" styleStr += ".items {" styleStr += "width:" + menuWidth + semi styleStr += "color:"+ fntCol + semi styleStr += "font-size:"+ fntSiz + semi styleStr += "font-weight:"+ fntWgh + semi styleStr += "font-style:"+ fntSty + semi styleStr += "font-family:"+ fntFam + semi styleStr += "border-width:" + borWid + semi styleStr += "border-color:" + borCol + semi styleStr += "border-style:" + borSty + semi styleStr += "line-height:" + linHgt + semi styleStr += "}" styleStr += "</STYLE>"; document.write(styleStr); if (perCentOver != null) { childOverlap = (perCentOver/100) * menuWidth } mSecsVis = secondsVisible*1000; imgStr = "<IMG SRC=" + imgSrc + " WIDTH=" + imgSiz + " HEIGHT=" + imgSiz +" BORDER=0 VSPACE=2 ALIGN=RIGHT>" topCount = 1; areCreated = false; isOverMenu = false; currentMenu = null; allTimer = null; function menuSetup(hasParent,lastItem,openCont,openItem) { this.menuOver = menuOver; this.menuOut = menuOut; this.onmouseover = this.menuOver; this.onmouseout = this.menuOut; this.keepInWindow = keepInWindow; this.showIt = showIt; this.hideTree = hideTree this.hideParents = hideParents; this.hideChildren = hideChildren; this.hideTop = hideTop; this.hasChildVisible = false; this.isOn = false; this.hideTimer = null; this.fullHeight = lastItem.top + lastItem.document.height; this.clip.bottom = this.fullHeight; if (hasParent) { this.hasParent = true; this.parentMenu = openCont; this.parentItem = openItem; this.parentItem.child = this; } else { this.hasParent = false; this.hideSelf = hideSelf; } } function itemSetup(arrayPointer,whichArray) { this.bgColor = backCol; this.clip.right = menuWidth; this.visibility = "inherit"; this.itemOver = itemOver; this.itemOut = itemOut; this.onmouseover = this.itemOver; this.onmouseout = this.itemOut; this.dispText = whichArray[arrayPointer]; this.linkText = whichArray[arrayPointer+1]; this.hasMore = whichArray[arrayPointer+2]; if (this.linkText.length>0) { this.linkIt = linkIt; this.onfocus = this.linkIt; } this.container = this.parentLayer; if (this.hasMore) { htmStr = imgStr + this.dispText; } else { htmStr = this.dispText; } layStr = "<SPAN CLASS=items>" + htmStr+ "</SPAN>"; this.document.write(layStr); this.document.close(); if (arrayPointer == 0) { this.top = 0; } else { this.top = this.prevItem.top + this.prevItem.document.height - borWid; } this.left = 0; } function makeElement(whichEl,whichContainer) { if (arguments.length==1) whichContainer = window; eval(whichEl + "= new Layer(menuWidth,whichContainer)"); return eval(whichEl); } function makeTop() { status = "Creating Hierarchical Menus"; while(eval("window.arMenu" + topCount)) { topArray = eval("arMenu" + topCount); topName = "elMenu" + topCount; topMenu = makeElement(topName); topMenu.setup = menuSetup; topItemCount = 0; for (i=0; i<topArray.length; i+=3) { topItemCount++; topItemName = "item" + topCount + "_" + topItemCount; topItem = makeElement(topItemName,topMenu); if (topItemCount >1) topItem.prevItem = eval("item" + topCount + "_" + (topItemCount-1)); topItem.setup = itemSetup; topItem.setup(i,topArray); if (topItem.hasMore) makeSecond(); } topMenu.setup(false,topItem); topCount++ } status = "Menus Created" areCreated = true; } function makeSecond() { secondCount = topCount + "_" + topItemCount; secondArray = eval("arMenu" + secondCount); secondName = "elChild" + secondCount; secondMenu = makeElement(secondName); secondMenu.setup = menuSetup; secondItemCount=0; for (j=0; j<secondArray.length; j+=3) { secondItemCount++; secondItemName = "item" + secondCount +"_" + secondItemCount; secondItem = makeElement(secondItemName,secondMenu) if (secondItemCount >1) secondItem.prevItem = eval("item" + secondCount + "_" + (secondItemCount-1)); secondItem.setup = itemSetup; secondItem.setup(j,secondArray); if (secondItem.hasMore) makeThird(); } secondMenu.setup(true,secondItem,topMenu,topItem); } function makeThird() { thirdCounter = secondCount + "_" + secondItemCount thirdArray = eval("arMenu" + thirdCounter); thirdName = "elGrandChild" + thirdCounter; thirdMenu = makeElement(thirdName) thirdMenu.setup = menuSetup; thirdItemCount=0; for (k=0; k<thirdArray.length; k+=3) { thirdItemCount++; thirdItemName = "item" + thirdCounter + "_" + thirdItemCount; thirdItem = makeElement(thirdItemName,thirdMenu); if (thirdItemCount >1) thirdItem.prevItem = eval("item" + thirdCounter + "_" +(thirdItemCount-1)); thirdItem.setup = itemSetup; thirdItem.setup(k,thirdArray); } thirdMenu.setup(true,thirdItem,secondMenu,secondItem); } function linkIt() { location.href = this.linkText; } function showIt(on) { this.visibility = (on) ? "show" : "hide"; } function keepInWindow() { scrBars = 20; winRight = (window.pageXOffset + window.innerWidth) - scrBars; rightPos = this.left + menuWidth; if (rightPos > winRight) { if (this.hasParent) { parentLeft = this.parentMenu.left; newLeft = ((parentLeft - menuWidth) + childOverlap); this.left = newLeft; } else { dif = rightPos - winRight; this.left -= dif; } } winBot = (window.pageYOffset + window.innerHeight) - scrBars; botPos = this.top + this.fullHeight; if (botPos > winBot) { dif = botPos - winBot; this.top -= dif; } } function popUp(menuName,e){ if (!areCreated) return; hideAll(); currentMenu = eval(menuName); xPos = e.pageX; yPos = e.pageY; currentMenu.moveTo(xPos,yPos); currentMenu.keepInWindow() currentMenu.isOn = true; currentMenu.showIt(true); } function popDown(menuName){ if (!areCreated) return; whichEl = eval(menuName); whichEl.isOn = false; whichEl.hideTop(); } function menuOver() { this.isOn = true; isOverMenu = true; currentMenu = this; if (this.hideTimer) clearTimeout(this.hideTimer); } function menuOut() { this.isOn = false; isOverMenu = false; } function itemOver(){ this.bgColor = overCol; if (this.container.hasChildVisible) { this.container.hideChildren(this); } if(this.hasMore) { this.childY = this.pageY + childOffset; this.childX = this.container.left + (menuWidth - childOverlap); this.child.moveTo(this.childX,this.childY); this.child.keepInWindow(); this.container.hasChildVisible = true; this.container.visibleChild = this.child; this.child.showIt(true); } } function itemOut() { this.bgColor = backCol; if (!isOverMenu) allTimer = setTimeout("currentMenu.hideTree()",10); } function hideAll() { for(i=1; i<topCount; i++) { temp = eval("elMenu" + i); temp.isOn = false; if (temp.hasChildVisible) temp.hideChildren(); temp.showIt(false); } } function hideTree() { allTimer = null; if (isOverMenu) return; if (this.hasChildVisible) { this.hideChildren(); } this.hideParents(); } function hideChildren(item) { if (this.visibleChild.hasChildVisible) { this.visibleChild.visibleChild.showIt(false); this.visibleChild.hasChildVisible = false; } if (!this.isOn || !item.hasMore || this.visibleChild != this.child) { this.visibleChild.showIt(false); this.hasChildVisible = false; } } function hideParents() { if (this.hasParent) { this.showIt(false); if (this.parentMenu.hasParent) { this.parentMenu.isOn = false; this.parentMenu.showIt(false); this.parentMenu.parentMenu.isOn = false; whichEl = this.parentMenu.parentMenu } else { this.parentMenu.isOn = false; whichEl = this.parentMenu; } } else { whichEl = this; } whichEl.hideTop(); } function hideTop() { whichEl = this; this.hideTimer = setTimeout("whichEl.hideSelf()",mSecsVis); } function hideSelf() { this.hideTimer = null; if (!this.isOn && !isOverMenu) { this.showIt(false); } } window.onload = makeTop;
Next column, we'll look at adapting this technique to Explorer 4, and create a cross-browser version.
Produced by Peter Belesis and
All Rights Reserved. Legal Notices.Created: Feb. 19, 1998
Revised: Feb. 19, 1998
URL: https://www.webreference.com/dhtml/column14/allCode3.html