0

I have created a simple dropdown menu with jquery

https://jsfiddle.net/pmksgz3w/

HTML

<ul>
  <li>Page A</li>
  <li>Page B
    <ul>
      <li>Dropdown</li>
      <li>Dropdown</li>
    </ul>
   </li>
</ul>

Jquery

$(document).ready(function(){
            $('ul> li').hover(function() {
                 $(this).find('ul').slideToggle();
            });
        });

When I hover over Page B, then the dropdown menu is shown. If I move the curser from Page B very slowly to the right (see picture) then the drop-down menu will close, since the li is not hovered for a short moment. How can I prevent that the dropdown menu will instantly close?

enter image description here

An even worse problem happens if I move the cursor extremely fast to the dropdown menu. Because then, the dropdown menu will slideUp and slideDown in an infinite loop.

I found at How to tell .hover() to wait? a promising solution from 2009 but the answer does not work when I try it,(Edit note: It works now, see edit below). Further it is mentioned that one should use hoverIntend plugin. I downloaded the plugin and changed my jQuery code to

$(document).ready(function(){
            $('ul> li').hoverIntend(function() {
                 $(this).find('ul').slideToggle();
            });
        });

and although it improves some things, the above problem that it instantly closes and the infinite loop remains. How can I solve this problem?


Edit: I managed to solve the first problem! Now the dropdown does not close instantly!

https://jsfiddle.net/5sxvsu8w/

I had to change the jQUery code as follows:

$(document).ready(function(){
    var timer;

    $('ul> li').hover(function() {
      clearTimeout(timer);
      $(this).find('ul').slideDown('fast');
    }, function() {
      var list = $(this).find('ul');
      timer= setTimeout(function() {
      list.slideUp('fast');
     }, 2000);
    });
});

However, the infinite loop problem remains.

Community
  • 1
  • 1
Adam
  • 25,960
  • 22
  • 158
  • 247

1 Answers1

2

The solution you found in here is usefull, this javascript code maybe can help:

$(document).ready(function(){
            
  $('.menu li').hover(
    function () {
        $('.sub', this).stop().slideDown(650);
    }, 
    function () {
        $('.sub', this).stop().slideUp(650);
    }
);

});




/*$('ul >li').hover(function() {
    clearTimeout($(this).data('timeout'));
    $('li > ul').slideDown('fast');
}, function() {
    var t = setTimeout(function() {
        $('li > ul').slideUp('fast');
    }, 650);
    $(this).data('timeout', t);
});*/
li{
  list-style-type:none;
  display: inline-block;
  position: relative;
  padding: 20px;
  background-color: #08c;
}

li ul li{
  min-width:200px;
}

li ul{
  margin:0;
  padding:0;
  position: absolute;
  top: 100%;
  left:0;
  display: none;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.1/jquery.min.js"></script>
<ul class="menu">
  <li>Page A</li>
  <li>Page B
    <ul class="sub">
      <li>Dropdown</li>
      <li>Dropdown</li>
    </ul>
   </li>
   
</ul>

EDIT: I have changed my javascript code after some reseach; this solution unfortunately does not solve completely the first problem (it is still based on a timer) but avoids the infinite loop.

Community
  • 1
  • 1
silviagreen
  • 1,679
  • 1
  • 18
  • 39
  • Thank you. Why does it not work when you replace **$('li > ul')** with **$(this).find('ul')** an in here https://jsfiddle.net/6v4vuvju/ ? If I hover once over **Page B** then move the curser away and return to **Page B** the dropdown-menu is not shown. Also, when I move the curser on **Page B** and then on the second **Dropdown** entriy, the dropdown-menu hides again. – Adam Feb 12 '16 at 16:06
  • @Adam I changed my answer to try to solve the problem you wrote in your comment and the infinite loop. I hope this can help. – silviagreen Feb 15 '16 at 14:28
  • perfect the `stop()` was exactly what I needed! – Adam Apr 28 '16 at 05:24