DHTML Lab: Hierarchical Menus Ver. 2 (Cross-Browser/Frames); The Complete Code 3/3
Hierarchical Menus Ver. 2 (Cross-Browser/Frames)
SPECIAL EDITION; the director's cut 3/3
Hierarchical Menus, Version 2: Routines (hierMenus.js)
This file, along with the external array file, may be downloaded in ZIP format.
/*hierMenus.js - Cross-Browser/Full-Window/Frames * By Peter Belesis. v2.0 980522 * 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. */ loader = (isFrames) ? (NS4) ? parent : parent.document.body : window; loader.onload = startIt; if (perCentOver != null) { childOverlap = (perCentOver/100) * menuWidth } mSecsVis = secondsVisible*1000; imgStr = "<IMG SRC=" + imgSrc + " WIDTH=" + imgSiz + " HEIGHT=" + imgSiz +" BORDER=0 VSPACE=2 ALIGN=RIGHT>" function initVars() { topCount = 1; areCreated = false; beingCreated = false; isOverMenu = false; currentMenu = null; allTimer = null; } initVars(); function startIt() { if (isFrames) { menuLoc = eval("parent.frames." + mainFrName); if (NS4) menuLoc.onunload = initVars; if (IE4) menuLoc.document.body.onunload = initVars; } else { menuLoc = window; } if (NS4) setTimeout("loader.onresize=reDo",100); makeTop(); } function makeTop(){ beingCreated = true; while(eval("window.arMenu" + topCount)) { makeMenu(false,topCount); topCount++ } if (IE4) { divColl = menuLoc.document.all.tags("DIV"); for (i=0; i<divColl.length; i++) { if (divColl[i].id.indexOf("elMenu")!=-1) { divColl[i].fullHeight = divColl[i].lastItem.style.pixelTop + divColl[i].lastItem.scrollHeight + (borWid*2); divColl[i].style.height = divColl[i].fullHeight; } } } status = (topCount-1) + " Hierarchical Menu Trees Created" areCreated = true; beingCreated = false; } function makeMenu(isChild,menuCount,parMenu,parItem) { menu = makeElement("elMenu" + menuCount); menu.array = eval("arMenu" + menuCount); menu.maxItems = menu.array.length / 3; menu.setup = menuSetup; menu.itemCount = 0; while (menu.itemCount < menu.maxItems) { menu.itemCount++; status = "Creating Hierarchical Menus: " + menuCount + " / " + menu.itemCount; prevItem = (menu.itemCount > 1) ? menu.item : null; itemName = "item" + menuCount + "_" + menu.itemCount; menu.item = makeElement(itemName,menu); menu.item.prevItem = prevItem; menu.item.setup = itemSetup; menu.item.setup(menu.itemCount,menu.array); if (menu.item.hasMore) { makeMenu(true,menuCount + "_" + menu.itemCount,menu,menu.item); menu = menu.parentMenu; } } menu.lastItem = menu.item; if (!isChild) parName = parItem = null; menu.setup(isChild,parMenu,parItem); } function makeElement(whichEl,whichContainer) { if (arguments.length==1) { whichContainer = (NS4) ? menuLoc : menuLoc.document.body; if (NS4) elWidth = menuWidth; } else { if (NS4) elWidth = menuWidth-(borWid*2)-(itemPad*2); } if (NS4) { eval(whichEl + "= new Layer(elWidth,whichContainer)"); } else { elStr = "<DIV ID=" + whichEl + " STYLE='position:absolute'></DIV>"; whichContainer.insertAdjacentHTML("BeforeEnd",elStr); if (isFrames) eval(whichEl + "= menuLoc." + whichEl); } return eval(whichEl); } function itemSetup(whichItem,whichArray) { this.onmouseover = itemOver; this.onmouseout = itemOut; arrayPointer = (whichItem-1)*3; this.dispText = whichArray[arrayPointer]; this.linkText = whichArray[arrayPointer + 1]; this.hasMore = whichArray[arrayPointer + 2]; if (this.linkText.length > 0) { if (NS4) { this.captureEvents(Event.MOUSEUP) this.onmouseup = linkIt; } else { this.onclick = linkIt; this.style.cursor = "hand"; } } htmStr = (this.hasMore) ? imgStr + this.dispText : this.dispText; if (NS4) { if (fntBold) htmStr = htmStr.bold(); if (fntItal) htmStr = htmStr.italics(); htmStr = htmStr.fontcolor(fntCol); htmStr = "<FONT FACE=" + fntFam + " POINT-SIZE=" + fntSiz + ">" + htmStr+ "</FONT>"; this.document.write(htmStr); this.document.close(); this.bgColor = backCol; this.visibility = "inherit"; this.container = this.parentLayer; 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 = menuWidth-(borWid*2)-itemPad; } else { with (this.style) { padding = itemPad; color = fntCol; fontSize = fntSiz + "pt"; fontWeight = (fntBold) ? "bold" : "normal"; fontStyle = (fntItal) ? "italic" : "normal"; fontFamily = fntFam; borderBottomWidth = separator + "px"; borderBottomColor = separatorCol; borderBottomStyle = "solid"; backgroundColor = backCol; } this.innerHTML = htmStr; this.container = this.offsetParent; if (whichItem == 1) { this.style.pixelTop = 0; } else { this.style.pixelTop = this.prevItem.style.pixelTop + this.prevItem.offsetHeight; } this.style.pixelLeft = 0; } } function menuSetup(hasParent,openCont,openItem) { this.onmouseover = menuOver; this.onmouseout = menuOut; this.showIt = showIt; this.keepInWindow = keepInWindow; this.hideTree = hideTree this.hideParents = hideParents; this.hideChildren = hideChildren; this.hideTop = hideTop; this.hasChildVisible = false; this.isOn = false; this.hideTimer = null; if (hasParent) { this.hasParent = true; this.parentMenu = openCont; this.parentItem = openItem; this.parentItem.child = this; } else { this.hasParent = false; this.hideSelf = hideSelf; } if (NS4) { this.bgColor = borCol; this.fullHeight = this.lastItem.top + this.lastItem.clip.bottom + borWid; this.clip.right = menuWidth; this.clip.bottom = this.fullHeight; } else { with (this.style) { width = menuWidth; borderWidth = borWid; borderColor = borCol; borderStyle = borSty; } this.lastItem.style.border=""; this.showIt(false); this.onselectstart = cancelSelect; this.moveTo = moveTo; this.moveTo(0,0); } } function popUp(menuName,e){ if (beingCreated) return; if (!beingCreated && !areCreated) startIt(); hideAll(); currentMenu = eval(menuName); if (!isFrames) { xPos = (NS4) ? e.pageX : event.x; yPos = (NS4) ? e.pageY : event.y; } else { if (IE4) menuLocBod = menuLoc.document.body; switch (navFrLoc) { case "left": xPos = (NS4) ? menuLoc.pageXOffset : menuLocBod.scrollLeft; yPos = (NS4) ? (e.pageY-pageYOffset)+menuLoc.pageYOffset : event.clientY + menuLocBod.scrollTop; break; case "top": xPos = (NS4) ? (e.pageX-pageXOffset)+menuLoc.pageXOffset : event.clientX + menuLocBod.scrollLeft; yPos = (NS4) ? menuLoc.pageYOffset : menuLocBod.scrollTop; break; case "bottom": xPos = (NS4) ? (e.pageX-pageXOffset)+menuLoc.pageXOffset : event.clientX + menuLocBod.scrollLeft; yPos = (NS4) ? menuLoc.pageYOffset+menuLoc.innerHeight : menuLocBod.scrollTop + menuLocBod.clientHeight; break; case "right": xPos = (NS4) ? menuLoc.pageXOffset+menuLoc.innerWidth : menuLocBod.scrollLeft+menuLocBod.clientWidth; yPos = (NS4) ? (e.pageY-pageYOffset)+menuLoc.pageYOffset : event.clientY + menuLocBod.scrollTop; break; } } currentMenu.moveTo(xPos,yPos); currentMenu.keepInWindow() currentMenu.isOn = true; currentMenu.showIt(true); } function menuOver() { this.isOn = true; isOverMenu = true; currentMenu = this; if (this.hideTimer) clearTimeout(this.hideTimer); } function menuOut() { if (IE4) { theEvent = menuLoc.event; if (theEvent.srcElement.contains(theEvent.toElement)) return; } this.isOn = false; isOverMenu = false; allTimer = setTimeout("currentMenu.hideTree()",10); } function itemOver(){ if (IE4) { theEvent = menuLoc.event; if (theEvent.srcElement.tagName == "IMG") return; this.style.backgroundColor = overCol; this.style.color = overFnt; } else { this.bgColor = overCol; } if (this.container.hasChildVisible) { this.container.hideChildren(this); } if (this.hasMore) { if (NS4) { this.childX = this.container.left + (menuWidth - childOverlap); this.childY = this.pageY + childOffset; } else { this.childX = this.container.style.pixelLeft + (menuWidth - childOverlap); this.childY = this.style.pixelTop + 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); } } function itemOut() { if (IE4) { theEvent = menuLoc.event; if (theEvent.srcElement.contains(theEvent.toElement) || (theEvent.fromElement.tagName=="IMG" && theEvent.toElement.contains(theEvent.fromElement))) return; this.style.backgroundColor = backCol; this.style.color = fntCol; } else { this.bgColor = backCol; if (!isOverMenu) { allTimer = setTimeout("currentMenu.hideTree()",10); } } } function moveTo(xPos,yPos) { this.style.pixelLeft = xPos; this.style.pixelTop = yPos; } function showIt(on) { if (NS4) {this.visibility = (on) ? "show" : "hide"} else {this.style.visibility = (on) ? "visible" : "hidden"} } function keepInWindow() { scrBars = 20; if (NS4) { winRight = (menuLoc.pageXOffset + menuLoc.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 = (menuLoc.pageYOffset + menuLoc.innerHeight) - scrBars; botPos = this.top + this.fullHeight; if (botPos > winBot) { dif = botPos - winBot; this.top -= dif; } } else { winRight = (menuLoc.document.body.scrollLeft + menuLoc.document.body.clientWidth) - scrBars; rightPos = this.style.pixelLeft + menuWidth; if (rightPos > winRight) { if (this.hasParent) { parentLeft = this.parentMenu.style.pixelLeft; newLeft = ((parentLeft - menuWidth) + childOverlap); this.style.pixelLeft = newLeft; } else { dif = rightPos - winRight; this.style.pixelLeft -= dif; } } winBot = (menuLoc.document.body.scrollTop + menuLoc.document.body.clientHeight) - scrBars; botPos = this.style.pixelTop + this.fullHeight; if (botPos > winBot) { dif = botPos - winBot; this.style.pixelTop -= dif; } } } function linkIt() { menuLoc.location.href = this.linkText; } function popDown(menuName){ if (!areCreated) return; whichEl = eval(menuName); whichEl.isOn = false; whichEl.hideTop(); } 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 hideTop() { whichEl = this; this.hideTimer = setTimeout("whichEl.hideSelf()",mSecsVis); } function hideSelf() { this.hideTimer = null; if (!this.isOn && !isOverMenu) { this.showIt(false); } } function hideParents() { tempMenu = this; while (tempMenu.hasParent) { tempMenu.showIt(false); tempMenu.parentMenu.isOn = false; tempMenu = tempMenu.parentMenu; } tempMenu.hideTop(); } function hideChildren(item) { tempMenu = this.visibleChild; while (tempMenu.hasChildVisible) { tempMenu.visibleChild.showIt(false); tempMenu.hasChildVisible = false; tempMenu = tempMenu.visibleChild; } if (!this.isOn || !item.hasMore || this.visibleChild != this.child) { this.visibleChild.showIt(false); this.hasChildVisible = false; } } function cancelSelect(){return false} function reDo(){ initVars(); menuLoc.location.reload() }
Produced by Peter Belesis and
All Rights Reserved. Legal Notices.Created: May. 22, 1998
Revised: May. 22, 1998
URL: https://www.webreference.com/dhtml/column20/allCode3.html