Horizontal Navigation Bar With Sub Menus

I would like to produce a horizontal nav bar, with a set of sub menus that pop up underneath. The tricky part, is that I don't want the menus to appear like the suckerfish menus, but to appear as a second row, on mouse over. For an example of what I am geting at, check out the xbox.com website (as opposed to the static way they are implemented on sites like apple.com).

Any tutorials/code/ideas would be appreciated.

Thanks
LVL 5
GENTPAsked:
Who is Participating?
I wear a lot of hats...

"The solutions and answers provided on Experts Exchange have been extremely helpful to me over the last few years. I wear a lot of hats - Developer, Database Administrator, Help Desk, etc., so I know a lot of things but not a lot about one thing. Experts Exchange gives me answers from people who do know a lot about one thing, in a easy to use platform." -Todd S.

ruggCommented:
html page
-----------------------
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head><title>Page Title</title>
<meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1" />
</head><body>
<div id="menuContainer"></div>
<h1>Page Header</h1>

<p>Page content</p>

<p>Page Footer</p>
<script type="text/javascript" src="horizMenu.js"></script>
</body></html>

horizMenu.js
------------------------------------------
//menuContainer
var menuArr = new Array("Search Engines","Code Pages","Personal");
var subMenuArr = new Array();
subMenuArr[0]=new Array("http://www.yahoo.com/|Yahoo","http://www.google.com/|Google","http://www.altavista.com/|Alta Vista");
subMenuArr[1]=new Array("http://www.experts-exchange.com/|Experts Exchange");
subMenuArr[2]=new Array("http://del.icio.us/|del.icio.us","http://www.myspace.com/|My Space");
//notice the site address and show name are separated with a pipe (|)

var menuTable = "<table width=\"100%\" style=\"background-color:#ffffcc;\"><tr>";
for(var i=0;i<menuArr.length;i++){
      menuTable += "<td onmouseover=\"fillSubMenu("+i+");\" align=\"center\">"+menuArr[i]+"</td>";
}
menuTable += "</tr></table>";
document.getElementById('menuContainer').innerHTML=menuTable;

var subTable = document.createElement("table");
subTable.style.width="100%";
subTable.style.backgroundColor="#cccccc";
var subBody = document.createElement("tbody");
subTable.appendChild(subBody);
var subTR = document.createElement("tr");
subBody.appendChild(subTR);
var subTD = document.createElement("td");
subBody.appendChild(subTD);
document.getElementById('menuContainer').appendChild(subTable);

function infanticide(obj){
      while(obj.childNodes[0]){
            obj.removeChild(obj.childNodes[0]);
      }
}

function fillSubMenu(i){
      var subm="";
      infanticide(subTR);
      for(var x=0;x<subMenuArr[i].length;x++){
            tArr=subMenuArr[i][x].split("|");
            var td = document.createElement("td");
            td.style.textAlign="center";
            var a = document.createElement("a");
            a.href=tArr[0];
            a.innerHTML=tArr[1];
            td.appendChild(a);
            subTR.appendChild(td);
      }      
}
LeeKowalkowskiCommented:
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/strict.dtd">
<html lang="en">
  <head>
    <title>Menu Demo</title>
    <style type="text/css">
      #mainMenu, .subMenu
      {
        list-style:none;
        text-align:center;
        margin:.25em;
        padding:0;
        border:1px solid #000;
      }
      #mainMenu li, .subMenu li
      {
        margin:0;
        padding:0 1em;
        display:inline;
      }
      #mainMenu a, .subMenu a
      {
        border-left:1px solid #000;
        border-right:1px solid #000;
        padding:0 2em;
      }
      #mainMenu a{background:#ccc;}
      .subMenu a{background:#9f9;}
      #mainMenu a:hover{background:#999;}
      .subMenu a:hover{background:#6c6;}
    </style>
    <script type="text/javascript">
      var menus = new Array();
   
      function initialiseMenu()
      {
        var mainMenu = document.getElementById("mainMenu");
        var links = mainMenu.getElementsByTagName("a");

        for(var i = 0; i < links.length; i++)
        {
          menus[i] = document.getElementById(links[i].rel);
          menus[i].style.display = "none";
          links[i].onmouseover = function(){this.timeout = setTimeout("showMenu('" + this.rel + "')", 1000);}
          links[i].onmouseout = function(){clearTimeout(this.timeout)}
        }
      }
     
      function showMenu(id)
      {
        for(var i = 0; i < menus.length; i++)
          menus[i].style.display = menus[i].id == id ? "" : "none";
      }
    </script>
  </head>
  <body onclick="{interval?stop():start();}">
    <ul id="mainMenu">
      <li><a href="#" rel="metal">Metal</a></li>
      <li><a href="#" rel="wood">Wood</a></li>
      <li><a href="#" rel="fruit">Fruit</a></li>
    </ul>
    <ul class="subMenu" id="metal">
      <li><a href="#">Gold</a></li>
      <li><a href="#">Silver</a></li>
      <li><a href="#">Bronze</a></li>
    </ul>
    <ul class="subMenu" id="wood">
      <li><a href="#">Oak</a></li>
      <li><a href="#">Pine</a></li>
      <li><a href="#">Beech</a></li>
    </ul>
    <ul class="subMenu" id="fruit">
      <li><a href="#">Apple</a></li>
      <li><a href="#">Orange</a></li>
      <li><a href="#">Banana</a></li>
    </ul>
    <script type="text/javascript">initialiseMenu();</script>
  </body>
</html>

- you should find it fairly straightforward, any questions, just ask.

Experts Exchange Solution brought to you by

Your issues matter to us.

Facing a tech roadblock? Get the help and guidance you need from experienced professionals who care. Ask your question anytime, anywhere, with no hassle.

Start your 7-day free trial
LeeKowalkowskiCommented:
Oh yeah, not forgetting *keyboard* access!  Change the onmouseover and onmouseout lines to this:

          links[i].onmouseover = links[i].onfocus = function(){this.timeout = setTimeout("showMenu('" + this.rel + "')", 1000);}
          links[i].onmouseout = links[i].onblur = function(){clearTimeout(this.timeout)}
C++ 11 Fundamentals

This course will introduce you to C++ 11 and teach you about syntax fundamentals.

GENTPAuthor Commented:
Thanks Lee, that was exactly what I was looking for!

Just a note, if you change the javascript from timing out at 1000 to timing out at 1, you'll notice a lot of the latency disapears.
LeeKowalkowskiCommented:
Yeah, but there is a deliberate delay on the XBOX website, so you can skip/tab past an item without it showing!  Admittedly 1000 is perhaps a bit long, but 300 should be quite nice.

If you want no delay whatsoever - then it's just:

links[i].onmouseover = links[i].onfocus = function(){showMenu(this.rel)};
(the onmouseout and onblur line can be deleted).

Perhaps I was thinking a little *too* similar to the XBOX site.
GENTPAuthor Commented:
I had thought about that, but as a user, I was looking it at is "wow, that's slow". The more I shortened it, the more I was like "this is looking more and more like a delay".

I hadn't thought of the benefits of being able to accidentally mouse over it without losing where you were, thanks for pointing that out.
It's more than this solution.Get answers and train to solve all your tech problems - anytime, anywhere.Try it for free Edge Out The Competitionfor your dream job with proven skills and certifications.Get started today Stand Outas the employee with proven skills.Start learning today for free Move Your Career Forwardwith certification training in the latest technologies.Start your trial today
Web Development

From novice to tech pro — start learning today.