views:

150

answers:

2

Hello,

My first post here. I want to make a horizontal menu with submenu's sliding down on mouseover. I know I could use jQuery but this is to practice my javascript skills.

I use the following code:

var up = new Array()
var down = new Array()
var submenustart

function titleover(headmenu, inter)
{
 submenu = headmenu.lastChild

 up[inter] = window.clearInterval(up[inter])
 down[inter] = window.setInterval("slidedown(submenu)",1)
}

function slidedown(submenu)
{
 if(submenu.offsetTop < submenustart)
 {
  submenu.style.top = submenu.offsetTop + 1 + "px"
 }
}

function titleout(headmenu, inter)
{
 submenu = headmenu.lastChild

 down[inter] = window.clearInterval(down[inter])
 up[inter] = window.setInterval("slideup(submenu)", 1)

}

function slideup(submenu)
{
 if(submenu.offsetTop > submenustart - submenu.clientHeight + 1)
 {
  submenu.style.top = submenu.offsetTop - 1 + "px"
 }
}

The variable submenustart gets appointed a value in another function which is not relevant for my question.
HTML looks like this:

<table class="hoofding" id="hoofding">
 <tr>
  <td onmouseover="titleover(this, 0)" onmouseout="titleout(this, 0)"><a href="#" class="hoofdinglink" id="hoofd1">AAAA</a>

  <table class="menu">
   <tr><td><a href="...">1111</a></td></tr>
   <tr><td><a href="...">2222</a></td></tr>
   <tr><td><a href="...">3333</a></td></tr>
  </table></td>

  <td onmouseover="titleover(this, 1)" onmouseout="titleout(this, 1)"><a href="#" class="hoofdinglink">BBBB</a>

  <table class="menu">
   <tr><td><a href="...">1111</a></td></tr>
   <tr><td><a href="...">2222</a></td></tr>
   <tr><td><a href="...">3333</a></td></tr>
   <tr><td><a href="...">4444</a></td></tr>
   <tr><td><a href="...">5555</a></td></tr>
  </table></td>
        ...
 </tr>
</table>

What happens is the following:
If I go over and out (for ex) menu A it works fine. If i go now over menu B the interval applied to A is now applied to B. There are now 2 interval functions applied to B. The one originally for A and a new one triggered by the mouseover on B. If I would go to A all the intervals are now applied to A.

I have been searching for hours but and I am completely stuck.

Thanks in advance.

A: 

AFAIK, (and according to the Gecko DOM reference) window.clearInterval() does not return anything, which maybe the reason which messes things up.

shinkou
True, but that doesn't seem to be the issue. The ID is being cleared and then the variable is set to undefined.
Justin Johnson
+2  A: 

My first suggestion is to

  1. Practice using semicolons properly and not relying on semicolon insertion
  2. Don't pass functions as strings (which requires an implicit eval)
  3. use JavaScript to attach events in a non-obtrusive manner

.

var up   = [],
    down = [],
    submenustart;

function titleover(headmenu, inter) {
    up[inter]   = window.clearInterval(up[inter]);
    down[inter] = window.setInterval(function() { slidedown(headmenu.lastChild); }, 1);
}

function slidedown(submenu) {
    if ( submenu.offsetTop < submenustart  ) {
        submenu.style.top = submenu.offsetTop + 1 + "px";
    }
}

function titleout(headmenu, inter) {
    down[inter] = window.clearInterval(down[inter]);
    up[inter]   = window.setInterval(function() { slideup(headmenu.lastChild); }, 1);
}

function slideup(submenu) {
    if ( submenu.offsetTop > submenustart - submenu.clientHeight + 1 ) {
        submenu.style.top = submenu.offsetTop - 1 + "px";
    }
}

My second suggestion is to not use tables for menus, as they aren't tabular data. Instead, use an unsorted list.

<ul class="hoofding" id="hoofding">
    <li onmouseover="titleover(this, 0)" onmouseout="titleout(this, 0)">
        <a href="#" class="hoofdinglink" id="hoofd1">AAAA</a>
        <ul class="menu">
            <li><a href="...">1111</a></li>
            <li><a href="...">2222</a></li>
            <li><a href="...">3333</a></li>
        </ul>
    </li>
    <li onmouseover="titleover(this, 1)" onmouseout="titleout(this, 1)">
        <a href="#" class="hoofdinglink">BBBB</a>
        <ul class="menu">
            <li><a href="...">1111</a></li>
            <li><a href="...">2222</a></li>
            <li><a href="...">3333</a></li>
        </ul>
    </li>
</ul>
Justin Johnson
Not passing the function as a string indeed solved the problem. Thanks.I will also take notice of your other suggestions.It seems I don't have enough reputation to vote up your anser. Otherwise you had my vote.
Roel V.