CBE Graphical mouseOver Pulldown Menu 3Updates11/18/02: Other CBE Menus...
9/25/02: You can download the menu images used in this example. 11/14/01: Upgrade to CBE v4. 7/5/01: NN4.77 seems to completely ignore this padding: 0px 6px;, so I'm trying this text-indent: 6px; instead. The only problem is that now if a menu item wraps, the wrapped line will not indent. BTW, I made a mistake on the last upload of this file - this one has the correction.
7/4/01: There was a problem with this menu on NN4.x, especially NN4.77. When vertical padding was
applied to the TD, strange things happened when there were no spaces in the menu items (sounds weird I know).
The solution (at least, so far this is a solution) was to apply no vertical padding to the TD, like this:
padding: 0px 6px;, and to get the vertical spacing by using this: line-height: 1.3em, even tho NN4.x
seems to add more space than the other browsers.
If you have any problems with it, please let me know. 6/19/01: I finally worked on these menus! This one works really well now. I've tested it on Win2K with IE5.00 and on Win98 with IE5.5, NN4.75, NS6.01, and Opera5.01. The Images
The menu labels are just images in a table.
Except for using absolutely positioned labels, this is the best way I've found to insure that the
menu boxes are positioned properly under their respective labels.
There are two images for each label - one is for the mouseover condition
Each menu box also uses a table. Their are four different types of rows in the table. The CSS
(1) The menuBar has width=100%. A table (with width=100%) is placed in this element, it will be as wide as the browser window. #menuBar { position:absolute; visibility:hidden; overflow:hidden; height:21px; width:250px; margin:0; padding:0; color:#000000; background:#000000; } .menuBox { position:absolute; visibility:hidden; overflow:hidden; width:156px; margin:0; padding:0px; } .mGfx { background:#c0c0c0; width:156px; height:2px; padding:0; margin:0; } .mItm { font-family: verdana,arial,sans-serif; font-size: 12px; width:144px; margin:0px; padding:0px; text-indent:6px; line-height:1.3em; color:#000000; background: #c0c0c0 url("../../images/mb_mid_156x1.jpg"); } The Javascript
As you know, the windowOnload() function gets called after CBE is initialized and the
cross-browser object model is in-place. Here, it performs the following tasks. var menuArray, activeMenu=1, menuBar, menuOpen=false; function windowOnload() { var i, menuCount=3; var menuBoxXOffset=0, // menuBox x offset from menuBar.left() menuBoxYOffset=1, // spacing between the label and it's menuBox menuLabelSpacing=2; // spacing between each label menuArray = new Array(); menuBar = document.getElementById('menuBar').cbe; menuBar.moveTo('n',75); // placement of the menuBar menuBar.show(); for (i = 1; i <= menuCount; ++i) { menuArray[i] = document.getElementById('menu'+i).cbe; menuArray[i].moveTo( menuBar.left() + menuBoxXOffset + ((i-1)*menuLabelSpacing), // x menuBar.top() + menuBar.height() + menuBoxYOffset // y ); menuArray[i].lblImg = 'label'+i; menuArray[i].lblOut = cbeNewImage("label"+i+"Out", "../../images/label"+i+"_out.jpg"); menuArray[i].lblOver = cbeNewImage("label"+i+"Over", "../../images/label"+i+"_over.jpg"); menuBoxXOffset += document.getElementById(menuArray[i].lblImg).width; } document.cbe.addEventListener("mousemove", menuHide); }
The function menuShow() is called by a mouseover event on one of the menu labels. function menuShow(e,mn) { if (mn == activeMenu && menuOpen) return; menuArray[activeMenu].hide() cbeSetImage(menuArray[activeMenu].lblImg, menuArray[activeMenu].lblOut); menuArray[mn].show(); cbeSetImage(menuArray[mn].lblImg, menuArray[mn].lblOver); activeMenu = mn; menuOpen = true; } The function menuHide() is the document.onMousemove event listener installed in windowOnload(). It constantly checks the current mouse position to see if it is within the rectangles defined by the menuBar or the active menuBox. The method contains() was modified in v3b12 just for this use. Notice that it now takes four "clipping" arguments. This allows you to define a "clipping region" on the element. If the mouse pointer is within that region, the function returns true. Notice that I'm using a negative value for the top argument. So you can have a space between the label and the box (Thanks for the idea smd!). If the mouse moves out of these regions, the active menuBox is hidden, the corresponding label is unrolled, and menuOpen is set to false. function menuHide(e) { if (!menuOpen) return; var x = e.pageX; var y = e.pageY; if (!menuArray[activeMenu].contains(x,y,-2,0,0,0) && !menuBar.contains(x,y)) { menuArray[activeMenu].hide(); cbeSetImage(menuArray[activeMenu].lblImg, menuArray[activeMenu].lblOut); menuOpen = false; } } With CBE v3, this file had its own image functions: imgLoad() and imgRoll(). But CBE v4 includes that functionality as part of the library with the methods: cbeNewImage() and cbeSetImage(). These methods are discussed in more detail here. The HTMLView the source of this page to get a better look at the HTML used for the menu. |