DHTML Lab: Hierarchical Menus Version 3 | 19
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; childOverlap = 50; childOffset = 5; perCentOver = null; secondsVisible = .5; fntCol = "blue"; fntSiz = "10"; fntBold = false; fntItal = false; fntFam = "sans-serif"; backCol = "#DDDDDD"; overCol = "#FFCCCC"; overFnt = "blue"; borWid = 1; borCol = "#CC0000"; borSty = "solid"; itemPad = 3; imgSrc = "tri.gif"; imgSiz = 10; separator = 1; separatorCol = "red"; keepHilite = true; NSfontOver = false; clickStart = true; clickKill = true; showVisited = ""; isFrames = false; Background Reading: startIt(): event capturing: NS click problem: NS resize bug: In script listings, cross-browser code is blue, Navigator-specific code is red, and Explorer code is green. |
startIt()The startIt() function, called when the page/frameset loads, has several important additions. function startIt() { isLoaded = true; if (isFrames) { menuLoc = eval("parent.frames." + mainFrName); if (NS4) { loader.captureEvents(Event.LOAD); loader.onload = NSloaded; menuLoc.onunload = NSunloaded; } if (IE4) { menuLoc.document.body.onunload = IEunloaded; } } else { menuLoc = window; } menuLoc.nav = nav = window; if (clickKill) { if (NS4) menuLoc.document.captureEvents(Event.MOUSEDOWN); menuLoc.document.onmousedown = clicked; } if (NS4) setTimeout("loader.onresize=reDo",2000); makeTop(); } First of all, isLoaded is set to true, since the page/frameset has now loaded. Next, we determine where the menus will appear, menuLoc, as in the previous versions. If the menus are in a frameset (isFrames), then we have new code for handling the main page load and unload. For Explorer, the unload event calls a new function, IEunloaded(). For Navigator, the procedure is a little more complicated. Capturing a Frame Load for NavigatorIn a frameset, the second statement in our script, loader.onload = startIt;directs the parent frameset to call startIt(), when its load event fires, that is, when all the child frames have loaded. In other words, when the frameset has completely loaded. A one-time occurrence. An immensely powerful and useful feature of the NS4 event capturing model is the ability of the frameset to capture all event firings of a type in all child frames. To achieve this, we must first capture an event, using the captureEvents() method. The following two statements tell the frameset to be on the alert for any load events in its children frames, and if a load event fires, to call the NSloaded() function: loader.captureEvents(Event.LOAD); loader.onload = NSloaded; The NSloaded() function looks like this: function NSloaded(e){ if (e.target.name == mainFrName) { initVars(); startIt(); } } This ability is only vaguely alluded to in the Netscape DHTML documentation. I discovered it by accident, and have not seen it used anywhere. It solves one of the main problems our menu script had: the re-creation of menus immediately upon a new page loading in the main frame! Here's how it works:
Menu Frame unloadWhen our menu frame unloads, the NSunloaded() function is called: menuLoc.onunload = NSunloaded; NSunloaded() simply sets isLoaded to false, as we are now in the process of loading a new page: function NSunloaded(){ isLoaded = false; } Arranging for Menu Hide with the click EventBack to our discussion of startIt(). If clickKill is true, startIt() captures the mousedown event for the document and directs it to the clicked() function. We want to capture the click event, but since NS4 has a quirky document.onclick, we use document.onmousedown for stable and similar results. The clicked() function will execute whenever a user presses a mouse button in your page, and hide the menus if they are not being navigated. if (clickKill) { if (NS4) menuLoc.document.captureEvents(Event.MOUSEDOWN); menuLoc.document.onmousedown = clicked; } We'll discuss clicked() later, when we look at the menu-hiding functions. Navigator resize Problem, RevisitedThere has been feedback on NS4 sometimes reloading a page endlessly. This is due to the load/resize bug documented in the DHTML Diner. To help avoid it, increase the millisecond interval between a load and the setting of the resize handler. Here we set it to 2000 (two seconds), hoping that the user does not resize the window in that time. If the user does resize the window, our standard reDo() function is called, here modified for added functionality: function reDo(){ initVars(); NSresized = true; menuLoc.location.reload(); } Our variables are initialized, the NSresized is set to true, and the menu window/frame is reloaded. The first two statements only have an effect if we are in a frameset document, as a full-page reload clears all variables. We'll come back to NSresized later, when discussing the menu display functions. For know, it must be mentioned that we need to track a window resize, since some of our script functionality will be lost. Our frameset load event capturing will be cancelled, so we will have to rebuild our menus manually. Once NSresized is set to true, it is never reset to false. When startIt() exits, it calls makeTop(), to begin menu creation. Before we get to menu creation, let's look at how we rebuild the menus automatically in Explorer |
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/hier3Start.html