[Last Call] Learn how to a build a cloud-first strategyRegister Now

x
?
Solved

Hiding multiple divs using setTimeOut

Posted on 2007-10-05
10
Medium Priority
?
533 Views
Last Modified: 2010-07-27
In an effort to improve my javaScript skills I've written a *basic* script to show popup menu's underneath a row of hyperlinks.  The idea is that once the cursor moves away from the hyperlink/displayed menu, then after a short delay the menu disappears.

The problem is that if I hover over 1 link, then immediately hover over another, the first popup menu never disappears because the first timer gets overwritten by the second timer.

Therefore, can anyone help me fine tune this script to correct make each popup menu disappear after a given time delay?

<script type="text/javascript">
            /* <![CDATA[ */
            var counterVar;
            
            function displayMenu(hoverMenuID, linkID){
                  var menu = document.getElementById(hoverMenuID);
                  if (menu) {
                        var positionToShowArray = findPos(linkID);
                        menu.style.left = positionToShowArray[0] + 'px';
                        menu.style.top = positionToShowArray[1] + 'px';
                        menu.style.display = '';
                        window.clearTimeout(counterVar);
                  }
            }
            
            function startCountDownForHidingMenu(hoverMenuID){
                  if (document.getElementById(hoverMenuID)) {
                        counterVar = window.setTimeout("hideMenu('"+hoverMenuID+"')", 1000);
                  }
            }
            
            function hideMenu(hoverMenuID){
                  var menu = document.getElementById(hoverMenuID);
                  if (menu) {
                        menu.style.display = 'none';
                  }
            }
            
            function findPos(obj) {
                  // omitted for brevity
            }
            /* ]]> */
      </script>
0
Comment
Question by:Rouchie
  • 5
  • 5
10 Comments
 
LVL 19

Expert Comment

by:dakyd
ID: 20022260
Maybe this is a stupid question, but why does the timeout need to be cleared when you mouse over the new menu item?  It seems like if you just let the timeout happen, it'd make the old menu disappear after a second, and your mouseover could happen by itself.

The only case I can see where it might be an issue would be if you mouseover the item that you just moused out of, but off the top of my head, I figure you can probably add a check for the ID's to prevent that.

Or is there something I'm overlooking?
0
 
LVL 25

Author Comment

by:Rouchie
ID: 20022342
>> The only case I can see where it might be an issue would be if you mouseover the item that you just moused out of, but off the top of my head

Yes that was the reason.  I didn't want menu's popping up that refused to disappear again!  My JS skills aren't too great so I was trying to keep it simple, but as long as I understand any answers here that make it work better then that's great!
0
 
LVL 19

Expert Comment

by:dakyd
ID: 20024746
>> I didn't want menu's popping up that refused to disappear again!
I think the issue would actually be the opposite.  Since the timeout is set, it would hide the menu after a second, even if you just finished mousing back over that item.

So, I'd suggest keeping the ID of the item that's going to disappear.  If it matches the ID of the item you moused over, then you clear the timeout.  Otherwise, you can leave the timeout alone, and it'll do its thing.

Give this a shot as a means to implement that:
<script type="text/javascript">
            /* <![CDATA[ */
            var counterVar;
            var idToBeHidden;
           
            function displayMenu(hoverMenuID, linkID){
                  var menu = document.getElementById(hoverMenuID);
                  if (menu) {
                        var positionToShowArray = findPos(linkID);
                        menu.style.left = positionToShowArray[0] + 'px';
                        menu.style.top = positionToShowArray[1] + 'px';
                        menu.style.display = '';
                        if (hoverMenuID == idToBeHidden)
                        {
                          window.clearTimeout(counterVar);
                          idToBeHidden = null;
                        }
                  }
            }
           
            function startCountDownForHidingMenu(hoverMenuID){
                  if (document.getElementById(hoverMenuID)) {
                        counterVar = window.setTimeout("hideMenu('"+hoverMenuID+"')", 1000);
                        idToBeHidden = hoverMenuID;
                  }
            }
           
            function hideMenu(hoverMenuID){
                  var menu = document.getElementById(hoverMenuID);
                  if (menu) {
                        menu.style.display = 'none';
                  }
            }
           
            function findPos(obj) {
                  // omitted for brevity
            }
            /* ]]> */
      </script>

I haven't had time to test the above (sorry, it's been a hectic day), but the idea is that you set a global ID variable whenever you set the timeout.  When you go to mouse over, you only clear the timeout if the ID of the item you moused over matches the global ID variable.  If they don't match, then you're dealing with separate menu items, and it's safe to hide.  

If you have issues, let us know.  Regardless, hope that helps.
0
Concerto's Cloud Advisory Services

Want to avoid the missteps to gaining all the benefits of the cloud? Learn more about the different assessment options from our Cloud Advisory team.

 
LVL 25

Author Comment

by:Rouchie
ID: 20032735
Hi dakyd,
Thanks for the post.  It does correctly hide the menus as I hoped, but there is one small problem:

The menus disappear when the mouse is hovered over the links within them.  So, the hover menu appears okay, but when you hover over a hover-menu link, the menu disappears (if that makes sense?)

It might be caused by the way I call the functions, but I'm confused...!
0
 
LVL 19

Expert Comment

by:dakyd
ID: 20034220
What does the HTML look like for one of the menu items?  Also, how are the functions being called?  I can take a few educated guesses about the javascript, but not the HTML.
0
 
LVL 25

Author Comment

by:Rouchie
ID: 20034319
Link to make the hover menu appear:

<a id="navbarLink05" onmouseover="displayMenu('about_hover', this)" onmouseout="startCountDownForHidingMenu('about_hover')" href="aboute4.aspx">About</a>

The hover menu div is like this:

<div id="products_hover" style="display:none;" onmouseover="displayMenu(this, 'navbarLink05')">
 <ul>
  <li>Link01</li>
  <li>Link02</li>
  <li>Link03</li>
 </ul>      
</div>
0
 
LVL 19

Expert Comment

by:dakyd
ID: 20034666
So where is the <a> in relation to the <div> that contains the sub-menu?

It looks like you're already using a list for the sub-menu items, is the <a> also a part of a list structure?
0
 
LVL 25

Author Comment

by:Rouchie
ID: 20039156
Yes the link is part of a list of links.  There are 2 hover menu div's, and these are directly underneath the link-list in the code, although their CSS rules dictate they obviously aren't shown.    The function called findPos(obj) places and displays each hover menu is the correct place.
0
 
LVL 19

Accepted Solution

by:
dakyd earned 2000 total points
ID: 20045917
Since you're already using lists, have you considered using a completely list-based drop down menu?  The suckerfish one is a good example: http://www.htmldog.com/articles/suckerfish/dropdowns/

This solves your problem because instead of the <div> being separate from the link that displays it, it's all together.  The end results is that mousing over the sub-menu doesn't trigger the mouseout, so the menu doesn't disappear.

It shouldn't be too hard to modify what you already have, but you will have to play with the CSS a little bit.  If you need some help, let us know.  Hope that helps.
0
 
LVL 25

Author Comment

by:Rouchie
ID: 20047255
The problem is that the suckerfish menu seems to rely on the list items being floated left.  The sub-menus can then appear directly underneath.  Normally this would be great but because my list is centered, the menus don't appear in the correct place.

I will investigate a padding attribute on the lists to see if I can correct it using the suckerfish script, but I would prefer my original script to correctly hide the menus if that's possible??
0

Featured Post

Prep for the ITIL® Foundation Certification Exam

December’s Course of the Month is now available! Enroll to learn ITIL® Foundation best practices for delivering IT services effectively and efficiently.

Question has a verified solution.

If you are experiencing a similar issue, please ask a related question

Introduction HTML checkboxes provide the perfect way for a web developer to receive client input when the client's options might be none, one or many.  But the PHP code for processing the checkboxes can be confusing at first.  What if a checkbox is…
This article discusses how to create an extensible mechanism for linked drop downs.
The viewer will learn the basics of jQuery, including how to invoke it on a web page. Reference your jQuery libraries: (CODE) Include your new external js/jQuery file: (CODE) Write your first lines of code to setup your site for jQuery.: (CODE)
The viewer will learn the basics of jQuery including how to code hide show and toggles. Reference your jQuery libraries: (CODE) Include your new external js/jQuery file: (CODE) Write your first lines of code to setup your site for jQuery…
Suggested Courses

825 members asked questions and received personalized solutions in the past 7 days.

Join the community of 500,000 technology professionals and ask your questions.

Join & Ask a Question