【问题标题】:simple jquery dropdown - clearTimeout, setTimeout issues简单的 jquery 下拉菜单 - clearTimeout、setTimeout 问题
【发布时间】:2010-02-23 05:01:27
【问题描述】:

HTML:

<ul class="topnav">
    <li><a href="#"><span>One</span></a></li>
    <li><a href="#"><span>Two</span></a></li>
    <li>
        <li><a href="#"><span>Three</span></a></li>
        <ul class="subnav">
            <li><a href="#">A</a></li>
            <li><a href="#">B</a></li>
            <li><a href="#">C</a></li>
        </ul>
    </li>
</ul>

jquery:

var timeout = null;

$(document).ready(function() {

    $("ul.topnav li").mouseover(function() {

        if (timeout) clearTimeout(timeout);

        $(this).find("ul.subnav").slideDown('fast').show();

    }).mouseout(function() {
        timeout = setTimeout(closemenu, 500);
    });

    // sub menu mouseovers keep dropdown open
    $("ul.subnav li").mouseover(function() {
        if (timeout) clearTimeout(timeout);
    }
    ).mouseout(function() {
        timeout = setTimeout(closemenu, 500);
        // alert(timeout);

    });

    // any click closes
    $(document).click(closemenu);
});

// Closes all open menus 
function closemenu() {
    $('ul.subnav:visible').hide();
    if (timeout) clearTimeout(timeout);
} 

我遇到了超时问题。在使用中,如果我将鼠标悬停在“三”上,下拉菜单将永远存在。如果我将鼠标悬停在“A”上,下拉菜单将永远消失,但如果我将鼠标悬停在“B”或更低的位置,菜单将关闭我。如果您取消注释“//警报(超时);”它为 B(和 A)到达那里,但超时将有一个值。为什么是这样?我认为 clearTimeout 会使超时变量为空?

【问题讨论】:

    标签: jquery drop-down-menu settimeout


    【解决方案1】:

    您可以像这样使用.hover() 和.data() 来整体简化代码:

    $(function() {
      $("ul.topnav li").hover(function() {
        var timeout = $(this).data("timeout");
        if(timeout) clearTimeout(timeout);
        $(this).find("ul.subnav").slideDown('fast');
      }, function() {
          $(this).data("timeout", setTimeout($.proxy(function() {
              $(this).find("ul.subnav").slideUp();
          }, this), 500));
      });
      $(document).click(function() {
          $('ul.subnav:visible').hide();
      });
    });​
    

    You can see a working demo here

    不是共享一个全局变量timeout,而是设置一个超时per顶级&lt;li&gt;,每个都有一个独立的计时器,当你将鼠标悬停在那个元素上时,只有它的计时器被清除。同样.hover()使用mouseenter和mouseleave,而不是mouseover和mouseout,区别在于当你进入一个孩子或孩子之间时,mouseenter不会再次触发,而mouseleave不会不要向我们关心的父 &lt;li&gt; 开火。

    您可以使用上面的演示链接对此进行测试,我也在第一个菜单中添加了子项,以证明它们是独立的。如果您碰巧对那里的$.proxy 有疑问,它只是在该超时匿名函数中使this 引用我想要的(当前的this)...在超时后需要关闭的元素.

    【讨论】:

      【解决方案2】:

      您正在尝试构建一个下拉菜单?为什么不使用现有的 jquery 插件,或者更好的是,像 http://purecssmenu.com/ 这样的 css-only 下拉菜单?

      【讨论】:

      • 我正在尝试将其添加到现有的网站菜单中,因此我试图尽可能走最简单的路线
      猜你喜欢
      • 1970-01-01
      • 2011-04-13
      • 2012-01-01
      • 1970-01-01
      • 2012-02-26
      • 1970-01-01
      • 1970-01-01
      • 2011-03-02
      • 1970-01-01
      相关资源
      最近更新 更多