admin管理员组

文章数量:1414908

I tried this js code:

<script type="text/javascript">

       $(document).ready( function() {
            var timer;
            $('.top-menu-first-ul li').hover(function(){
                        if(timer) {
                                clearTimeout(timer);
                                timer = null
                        }
                        timer = setTimeout(function() {
                                   $(this).find('ul').slideToggle(100);
                        }, 500)
            },
            // mouse out
            });
        });


</script>

with this html:

<ul class="top-menu-first-ul">
    <li>
        <a href="">Google</a>
        <ul class="top-menu-second-ul">
            <li><a href="">Google Translate</a></li>
            <li><a href="">Google Images</a></li>
            <li><a href="">Gmail</a></li>
            <li><a href="">Google Plus</a></li>
        </ul>
    </li>
    <li>
        <a href="">Facebook</a>
    </li>
    <li>
        <a href="">Twitter</a>
    </li>
</ul>

but it is not working.

I would like to show the submenu when hovering over e.g. Google link and other will appear after 300ms.

So, I need to prevent loading submenu when the user just quickly hover over it and not stay on hover link for at least 300ms.

Then I need to stop executing code (or slide up) when he leaves the link. Because if he go over and back and over and back a copule of times he stop doing hovering anfd the code is still executing itself how many times he had hover over the link. I need somehow prevent this to happen.

EDIT: I need to solve this without plugins like hoverIntent etc. if possible, just plain javascript and jQuery

I tried this js code:

<script type="text/javascript">

       $(document).ready( function() {
            var timer;
            $('.top-menu-first-ul li').hover(function(){
                        if(timer) {
                                clearTimeout(timer);
                                timer = null
                        }
                        timer = setTimeout(function() {
                                   $(this).find('ul').slideToggle(100);
                        }, 500)
            },
            // mouse out
            });
        });


</script>

with this html:

<ul class="top-menu-first-ul">
    <li>
        <a href="http://google.">Google</a>
        <ul class="top-menu-second-ul">
            <li><a href="http://translate.google.">Google Translate</a></li>
            <li><a href="http://images.google.">Google Images</a></li>
            <li><a href="http://gmail.google.">Gmail</a></li>
            <li><a href="http://plus.google.">Google Plus</a></li>
        </ul>
    </li>
    <li>
        <a href="http://facebook.">Facebook</a>
    </li>
    <li>
        <a href="http://twitter.">Twitter</a>
    </li>
</ul>

but it is not working.

I would like to show the submenu when hovering over e.g. Google link and other will appear after 300ms.

So, I need to prevent loading submenu when the user just quickly hover over it and not stay on hover link for at least 300ms.

Then I need to stop executing code (or slide up) when he leaves the link. Because if he go over and back and over and back a copule of times he stop doing hovering anfd the code is still executing itself how many times he had hover over the link. I need somehow prevent this to happen.

EDIT: I need to solve this without plugins like hoverIntent etc. if possible, just plain javascript and jQuery

Share Improve this question edited Sep 8, 2012 at 21:37 Derfder asked Sep 8, 2012 at 21:30 DerfderDerfder 3,32411 gold badges52 silver badges85 bronze badges
Add a ment  | 

2 Answers 2

Reset to default 6

Use stop() to prevent animation weirdness and delay() to wait 300ms. Also hover() is deprecated I would suggest using on() instead:

$('.top-menu-first-ul li').on({
  mouseover: function() {
    $(this).find('ul').stop(1,1).delay(300).slideDown(100);
  },
  mouseleave: function() {
    $(this).find('ul').stop(1,1).slideUp(100);
  }
});

Demo: http://jsfiddle/elclanrs/6dtWz/

I think that problem is that you use $(this) inside your function which is called in timeout. $(this) inside this closure is not the same as outside (inside jQuery event handler where jQuery sets it for you). Here (jsfiddle) is the solution:

$(document).ready( function() {
            $('.top-menu-first-ul li').mouseenter(mouseIn);
            $('.top-menu-first-ul li').mouseout(mouseOut);
});
function mouseIn(e){
    var target = $(this);
    var timer = setTimeout(function() {
                   target.find('ul').slideDown(100);
        }, 500);
    target.attr("data-timer", timer);
}

function mouseOut(e){
    var target = $(this);
    var timer = target.attr("data-timer");
    if(timer){
        clearTimeout(timer);
    }
    target.find('ul').slideUp(100)
}
​

UPDATE This solution is based on yours, but I suggest to use @elclanrs's solution, as it is better (more readable, uses jQuery API which is intended for this).

本文标签: javascriptWait 300ms and then slide down menu using jQueryStack Overflow