Previous Page
Next Page

Adding Pull-Down Menus

You may have looked at the sliding menus in the previous task and said to yourself, that's nice, but what I really want are those pull-down menus that make Web pages look like applications. Here's the secret: there's not a lot of difference between the previous task and this one. In fact, the HTML is identical (just refer back to Script 14.1); the CSS is in Script 14.4, and the JavaScript is in Script 14.5.

Script 14.4. A little more CSS and a little more JavaScript give your menus a more traditional look.

body {
     background-color: white;
     color: black;
}

div {
     margin-bottom: 10px;
     width: 180px;
     background-color: #CF9;
}

ul.menu {
     display: none;
     list-style-type: none;
     margin: 0;
     padding: 0;
}

ul.menu li {
     font: 12px arial, helvetica, sans-serif;
     padding-left: 10px;
}

a.menuLink, li a {
     text-decoration: none;
     color: #060;
}

a.menuLink {
     font-size: 16px;
     font-weight: bold;
}

li a:hover {
     background-color: #060;
     color: white;
}

Script 14.5. This script turns your everyday links into pull-down menus.

window.onload = initAll;

function initAll() {
     var allLinks = document.getElementsByTagName("a");

     for (var i=0; i<allLinks.length; i++) {
        if (allLinks[i].className.indexOf("menuLink") > -1) {
           allLinks[i].onclick = function() {return false;}
           allLinks[i].onmouseover = toggleMenu;
        }
     }
}

function toggleMenu() {
     var startMenu = this.href.lastIndexOf("/")+1;
     var stopMenu = this.href.lastIndexOf(".");
     var thisMenuName = this.href.substring(startMenu,stopMenu);

     document.getElementById(thisMenuName).style.display = "block";

     this.parentNode.className = thisMenuName;
     this.parentNode.onmouseout = toggleDivOff;
     this.parentNode.onmouseover = toggleDivOn;
}

function toggleDivOn() {
     document.getElementById(this.className).style.display = "block";
}

function toggleDivOff() {
     document.getElementById(this.className).style.display = "none";
}

To add a pull-down menu:

1.
allLinks[i].onclick = function() {return false;}
allLinks[i].onmouseover = toggleMenu;



Instead of adding an onclick handler to call toggleMenu() as we did previously, here, we set onclick to always return falsewe don't want it to do anything at all. Instead, we'll have onmouseover call toggleMenu(), which means that the menu will open up whenever we move the mouse over it (Figure 14.3).

Figure 14.3. The menus expand when you roll the mouse over them, highlighting the choice under the mouse pointer.


2.
document.getElementById  (thisMenuName).style.display = "block";



Down in toggleMenu(), we're not toggling quite the same way any more. Instead, we're now just going to set this menu to always display.

3.
this.parentNode.className = thisMenuName;
this.parentNode.onmouseout = toggleDivOff;
this.parentNode.onmouseover = toggleDivOn;



Once we've set the menu to display, we have to figure out how to hide it again. The secret to a pull-down menu is that you don't want it to close when you move the mouse off the triggering link; you want it to close when you move the mouse off the entire div. That is, if you're anywhere on the menu, you want it to stay open. Here, we assign a class to the parent of the current link (that's the div around the link), and then we assign onmouseover and onmouseout handlers to the div. These trigger toggleDivOn() and toggleDivOff(), which will handle the div from now on.

Here's the trick: if we got here, then by definition, the cursor is inside the div. And consequently, just setting the onmouseover causes toggleDivOn() to be immediately triggered.

4.
document.getElementById(this. className).style.display = "block";



Here are the entire contents of toggleDivOn(), in which we tell the entire div to (again) display. Yes, we did it above in step 2, but we need to do it again here; otherwise, the moment we moved off the link, the menu would snap shut again.

5.
document.getElementById (this.classsName).style.display = "none";



And here's where we do the reverse of toggleDivOn() inside toggleDivOff(). Instead of setting the div to always display, we set it to hidebut only when the cursor moves off the entire div area.

Script 14.6. Add one line of CSS, and you get an entirely new look to your menus.

body {
     background-color: white;
     color: black;
}

div {
     margin-bottom: 10px;
     width: 180px;
     background-color: #CF9;
     float: left;
}

ul.menu {
     display: none;
     list-style-type: none;
     margin: 0;
     padding: 0;
}

ul.menu li {
     font: 12px arial, helvetica, sans-serif;
     padding-left: 10px;
}

a.menuLink, li a {
     text-decoration: none;
     color: #060;
}

a.menuLink {
     font-size: 16px;
     font-weight: bold;
}

li a:hover {
     background-color: #060;
     color: white;
}

Tips

  • But now you're saying, "I don't want a vertical menu; I want a horizontal menu!" Okay, okayhere's the sneaky trick: add float: left; to the CSS for each menu div, as shown in Script 14.6 and Figure 14.4. Yes, that's all it takes to turn one into anotherno JavaScript changes required.

    Figure 14.4. A simple change to the CSS makes the menus appear across the page, rather than down the left side.

  • Here's some of what's going on inside these menus: if you take a close look at the HTML, the links are actually inside <ul> and <li> tagsthat is, they're unordered lists and list items. If a user has a browser that doesn't support CSS, they'll just see a list of items on the page (Figure 14.5). If the browser is capable, though, we can use CSS to style how we want those lists to look, with a result that looks nothing like a plain list.

    Figure 14.5. When you turn off the CSS display, as we have done here in Firefox, the menus are revealed for what they really are: just a simple unordered list.



Previous Page
Next Page