// The most important event is one used to display the menu by calling one of several methods of // any menu object(s) you have created. This is where you select the menu creation mode. 'Dynamic' // mode inserts the menus into the document once it has finished loading and supports features // like modifying the menu after creation. You update a menu in 'Dynamic' mode by just calling the // .update() method of a menu object like 'pMenu'. // 'Fast' creation mode writes the menus to the document here and now, which is faster and // more reliable in many browsers but only when the document's loading -- you do this by passing // 'true' without quotes to the update function to signal that we're inline. // Opera only supports Fast mode and Netscape 4 only supports in Dynamic mode, so we use // browser-detect code here. If you find some browser has troubles with one mode or another, try // the other menu creation method -- see the "Cross-Browser" code at the very top of the SCRIPT // tag for the variables used. // Hardcore tweakers -- there's some extra code commented in the popOver() function at the top // which lets you create the root menu on page load and other menus only as needed, which might // be useful for very very large menus in a single frame. Look it up if you want. if (!isNS4) { // Write menus now in non-NS4 browsers, by calling the "Fast" mode .update(true) method. pMenu.update(true); //anotherMenu.update(true); } else { // For Netscape 4, back up the old onload function and make a new one to update our menus. // This is the regular "Dynamic" mode menu update, it works in IE and NS6 too if required. var popOldOL = window.onload; window.onload = function() { if (popOldOL) popOldOL(); pMenu.update(); //anotherMenu.update(); } } // Other events must be assigned, these are less complicated, just add or remove menu objects. var nsWinW = window.innerWidth, nsWinH = window.innerHeight, popOldOR = window.onresize; window.onresize = function() { if (popOldOR) popOldOR(); if (isNS4 && (nsWinW!=innerWidth || nsWinH!=innerHeight)) history.go(0); pMenu.position(); //anotherMenu.position(); } window.onscroll = function() { pMenu.position(); //anotherMenu.position(); } // NS4 can't reliably capture clicks on layers, so here's a workaround. if (isNS4) { document.captureEvents(Event.CLICK); document.onclick = function(evt) { with (pMenu) if (overI) click(overM, overI); //with (anotherMenu) if (overI) click(overM, overI); return document.routeEvent(evt); } } // Activate the window.onscroll() event in non-Microsoft browsers. if (!isIE || isOp) { var nsPX=pageXOffset, nsPY=pageYOffset; setInterval('if (nsPX!=pageXOffset || nsPY!=pageYOffset) ' + '{ nsPX=pageXOffset; nsPY=pageYOffset; window.onscroll() }', 50); } // *** (5) OPTIONAL CODE *** DELETE IF YOU'RE NOT USING THESE! // MOUSE EVENTS: // // If you want, you can assign functions to handle mouse events like mouse over/out/click. // You'll want to use these for assigning click actions to 'sm:' items or status messages etc. // 'with (this)' means use the properties of the menu object, and it's passed the current // menu name (mN) and item number (iN) you can use to calculate the active item. // To uncomment and activate, delete the /* and */ at the start and end. /* pMenu.onclick = function(mN, iN) { with (this) { // Do actions depending on the item that the mouse was over at the time of the click. // You may with to use nested IFs or 'switch' statements etc. if you're familiar with JS. if (mN == 'root') { if (iN == 1) status = 'Congratulations, you\'ve mastered clicking!'; // Click on second item in root menu will navigate to 'edit.html'. Copy and paste this for // each menu item to add click actions to 'sm:' items... if (iN == 2) location.href = 'edit.html'; if (iN == 3) location.href = 'help.html'; } }} // Set the status message to the URL if the 'action type' is nothing, and clear on mouseout. pMenu.onmouseover = function(mN, iN) { with (this) { // By now, you either have my JS Object Browser script from my site or you need it... try // embedding in an IFrame and typing 'pMenu' into its Go To field to see the menu internals. with (menu[mN][iN]) if (!type) status = href; }} pMenu.onmouseout = function() { status = '' } */ // ANIMATION: // // Each menu object you create by default shows and hides its menus instantaneously. // However you can override this behaviour with custom show/hide animation routines, // as we have done in the "Menu Effects" section. Feel free to edit this, or delete // this entire function if you're not using it. Basically, make functions to handle // menuObj.showMenu() and .hideMenu(), both of which are passed menu names. // // Customisers: My lyr.clip() command gets passed the parameters (x1, y1, x2, y2) // so you might want to adjust the direction etc. Oh, and I'm adding 2 to the dimensions // to be safe due to different box models in some browsers. // Another idea: add some if/thens to test for specific menu names...? function menuAnim(menuObj, menuName, dir) { // The array index of the named menu (e.g. 'mFile') in the menu object (e.g. 'pMenu'). var mD =[menuName][0]; // Add timer and counter variables to the menu data structure, we'll need them. if (!mD.timer) mD.timer = 0; if (!mD.counter) mD.counter = 0; with (mD) { // Stop any existing animation. clearTimeout(timer); // If the layer doesn't exist (cross-frame navigation) quit. if (!lyr || !lyr.ref) return; // Show the menu if that's what we're doing. if (dir>0) lyr.vis('visible'); // Also raise showing layers above hiding ones. lyr.sty.zIndex = 1001 + dir; // Alpha fade in IE5.5+. Mozilla's opacity isn't well suited to this as it's an inheritable // property rather than a block-level filter, and it's slow, but uncomment and try it perhaps. // WARNING: This looks funny if you're mixing opaque and translucent items e.g. solid menus // with dropshadows. If you're going to use it, make sure all your alpha values for a given // menus are numbers, or they're all null (solid). //if (isIE && window.createPopup) lyr.alpha(counter&&(counter<100) ? counter : null); // Clip the visible area. Tweak this if you want to change direction/acceleration etc. lyr.clip(0, 0, menuW+2, (menuH+2)*Math.pow(Math.sin(Math.PI*counter/200),0.75) ); // Remove clipping in NS6 on completion, seems to help old versions. if ((isDOM&&!isIE) && (counter>=100)) lyr.sty.clip=''; // Increment the counter and if it hasn't reached the end (10 steps either way), // set the timer to call the show/hide function again in 40ms. counter += dir; if (counter>100) counter = 100; else if (counter<0) { counter = 0; lyr.vis('hidden') } else timer = setTimeout(menuObj.myName+'.'+(dir>0?'show':'hide')+'Menu("'+menuName+'")', 40); } } // Here's the alternative IE5.5+ filter animation function. function menuFilterShow(menuObj, menuName, filterName) { var mD =[menuName][0]; with (mD.lyr) { sty.filter = filterName; var f = ref.filters; if (f&&f.length&&f[0]) f[0].Apply(); vis('visible'); if (f&&f.length&&f[0]) f[0].Play(); } } // BORDERS AND DROPSHADOWS: // // Here's the menu border and dropshadow functions we call above. Edit ot delete if you're // not using them. Basically, they assign a string to[0].extraHTML, which // is written to the document with the menus as they are created -- the string can contain // anything you want, really. They also adjust the menu dimensions and item positions // to suit. Dig out the Object Browser script and open up "pMenu" for more info. function addMenuBorder(mObj, iS, alpha, bordCol, bordW, backCol, backW) { // Loop through the menu array of that object, finding matching ItemStyles. for (var mN in { var[mN], dS='
'; else mR[0].extraHTML += dS+bordCol+'; left:0px; top:0px; width:'+mW+'px; height:'+mH+ 'px; z-index:980; '+(alpha!=null?'filter:alpha(opacity='+alpha+'); -moz-opacity:'+(alpha/100):'')+ '">'+dS+backCol+'; left:'+bordW+'px; top:'+bordW+'px; width:'+(mW-2*bordW)+'px; height:'+ (mH-2*bordW)+'px; z-index:990">
'; } } function addDropShadow(mObj, iS) { // Pretty similar to the one above, just loops through list of extra parameters making // dropshadow layers (from arrays) and extending the menu dimensions to suit. for (var mN in { var a=arguments,[mN][0], addW=addH=0; if (mD.itemSty != iS) continue; for (var shad=2; shad'; else mD.extraHTML += '
'; addW=Math.max(addW, s[2]+s[4]); addH=Math.max(addH, s[3]+s[5]); } mD.menuW+=addW; mD.menuH+=addH; } } // Extra code for updating and moving the menus is embedded in the feature list in the HTML document // below, have a look at that if you're interested in tweaking the menu more. // *** (6) FRAMESET README *** // You're looking at the single-frame version of this script right now. This menu does support // frames with a few extensions -- the core script is the same, but you need to remove the "Events" // section and include a modified version of it in each loaded file. Get the frameset example from // my site first, I've put the modified section in a file named "SUBFR.JS". // // This script should reside in the topmost frameset. Files loaded in this frameset must satisfy // two conditions to work: // // 1) They must have all the needed CSS info from the 1