This is my best menu yet. It works in IE4up, Gecko, Konquerer, and Opera. It downgrades in anything else.
Here's a template for this menu.
There are several current discussions on this menu. I welcome your comments, bug-reports, browser-tests, etc...
Menu Version...
Page Version...
The number of nested menus is unlimited.
Almost no javascript editing is required to adapt the menu to your page.
The HTML consists of nested DIV's so the menu downgrades very well.
The menu is very quick and responsive. It is also very extensible.
Special thanks to everyone who helped with testing.
The dynamic menu has been tested with...
The downgrade menu has been tested with...
In the file menu9.js you'll see...
document.write("<script type='text/javascript' src='../cbe_core.js'></script>"); document.write("<script type='text/javascript' src='../cbe_event.js'></script>");If you have the '.js' files in the same folder as the '.html' file, then change the above to the following:
document.write("<script type='text/javascript' src='cbe_core.js'></script>"); document.write("<script type='text/javascript' src='cbe_event.js'></script>");
Also in menu9.js you'll see...
cbeMenu = new cbeDropdownMenu( mnuMarker.pageX(), mnuMarker.pageY(), // coord of first label 75, 20, // label width and height 120, // box width 18, // item height 2, // item left padding '#336699', // background color '#00cccc', // text color '#00cccc', // hover background color '#336699' // hover text color );
This code instantiates the cbeDropdownMenu object. The arguments provide for the position, sizes, and colors of the menu. That's it - that's the only javascript that has to be edited.
There are two CSS files:
menu9_def.css - This is the default CSS which provides styling for the page and the menu.
menu9_abs.css - This CSS is only included if the menu does not downgrade. It adds positioning properties to the menu's css classes.
There are 3 CSS classes: mLabel, mBox, and mItem. They have CSS rules in both files.
The only HTML requirement is that you follow a few simple naming and structural conventions.
Every label, box, and item is a DIV. The main labels must have id's like this... label1, label2, label3, etc. That's the only id naming requirement. Of course the other DIVs must have unique id's - but it doesn't matter what they are.
There are 3 CSS classes: mLabel, mBox, and mItem. The following example defines one mLabel, one mBox, and two mItems.
<div id='label1' class='mLabel'>Label 1</div> <div id='b1' class='mBox'> <div id='i11' class='mItem'><a class="m" href="#">Item 11</a></div> <div id='i12' class='mItem'><a class="m" href="#">Item 12</a></div> </div>
The following example defines two mLabels which will appear as the two main labels on a horizontal menubar. Each main label has its associated mBox. The first box has two mItems. Following the first mItem is a mBox - a sub-menu. The mItem immediately before a mBox becomes the sub-label for the nested box.
<div id='label1' class='mLabel'>Label 1</div> <div id='b1' class='mBox'> <div id='i11' class='mItem'><a class="m" href="#">Sub Label</a></div> <div id='b11' class='mBox'> <div id='i111' class='mItem'><a class="m" href="#">Item 111</a></div> <div id='i112' class='mItem'><a class="m" href="#">Item 112</a></div> </div> <div id='i12' class='mItem'><a class="m" href="#">Item 12</a></div> </div> <div id='label2' class='mLabel'>Label 2</div> <div id='b2' class='mBox'> <div id='i21' class='mItem'><a class="m" href="#">Item 21</a></div> <div id='i22' class='mItem'><a class="m" href="#">Item 22</a></div> </div>
Only the main labels (the labels that will appear as on a menubar) will be of class mLabel. All sub-labels will be of class mItem, because they are items contained in a box.
The id's for the main labels in the above example are 'label1' and 'label2'. All the remaining DIV's must have unique id's but it doesn't matter what names you use.
Everything you need to implement this menu is included in the CBE download package.
// begin class cbeDropdownMenu function cbeDropdownMenu(mnuX, mnuY, lblW, lblH, boxW, itmH, itmPad, bgColor, txtColor, hvrBColor, hvrTColor) { // Properties this.mnuX = mnuX; this.mnuY = mnuY; this.lblW = lblW; this.lblH = lblH; this.boxW = boxW; this.itmH = itmH; this.itmPad = itmPad; this.bgColor = bgColor; this.txtColor = txtColor; this.hvrBColor = hvrBColor; this.hvrTColor = hvrTColor; this.lblCount = 0; this.lblActive = null; // Methods this.paint = function(mnuX, mnuY) { // this is the only public method if (arguments.length > 0) this.mnuX = mnuX; if (arguments.length > 1) this.mnuY = mnuY; var lbl = null; // of type Element var box = null; // of type CBE var mX = this.mnuX; this.lblCount = 0; do { ++this.lblCount; lbl = cbeGetElementById('label' + this.lblCount) if (lbl) { with (lbl.cbe) { color(this.txtColor); background(this.bgColor); zIndex(2002); resizeTo(this.lblW, this.lblH); moveTo(mX, this.mnuY); show(); } if (lbl.cbe.nextSibling && lbl.cbe.nextSibling.id.indexOf('label')==-1) box = lbl.cbe.nextSibling; else box = null; lbl.cbe.childBox = box; lbl.cbe.parentLabel = null; if (box) this.paintBox(box, lbl.cbe, mX, this.mnuY + lbl.cbe.height()); mX += lbl.cbe.width(); } } while(lbl); --this.lblCount; } this.paintBox = function(box, parent, x, y) { var mx=0, my=4, itmCount=0; box.background(this.bgColor); box.width(this.boxW); box.moveTo(x, y); box.zIndex(2002); var itm = box.firstChild; while (itm) { if (itm.id.indexOf('i') != -1) { itm.color(this.txtColor); itm.background(this.bgColor); itm.resizeTo(this.boxW - 6, this.itmH); itm.moveTo(mx + this.itmPad, my); itm.show(); my += itm.height(); ++itmCount; } else { itm.previousSibling.childBox = itm; itm.previousSibling.parentLabel = parent; this.paintBox(itm, itm.previousSibling, mx + itm.parentNode.width() - 4, my - itm.previousSibling.height()); } itm = itm.nextSibling; } box.height(itmCount * this.itmH + 8); } this.mousemoveListener = function(e) { if ( this.lblActive && (e.cbeTarget != this.lblActive.childBox && e.cbeTarget != this.lblActive && e.cbeTarget.parentNode != this.lblActive.childBox) ) { if (this.lblActive.childBox) this.lblActive.childBox.hide(); this.lblActive.color(this.txtColor); this.lblActive.background(this.bgColor); this.lblActive = this.lblActive.parentLabel; } else if (e.cbeTarget.childBox || e.cbeTarget.id.indexOf('label')!=-1) { e.cbeTarget.color(this.hvrTColor); e.cbeTarget.background(this.hvrBColor); this.lblActive = e.cbeTarget; if (this.lblActive.childBox) this.lblActive.childBox.show(); } } // Constructor Code this.paint(); document.cbe.addEventListener('mousemove', this.mousemoveListener, false, this); } // end class cbeDropdownMenu
Label 1
|
Label 2
|
Label 3
|
Label 4
Sub Label»
Sub Label»
Sub Label»
Sub Label»
|