jquery - 简单的 jquery 下拉菜单 -clearTimeout、setTimeout 问题

标签 jquery drop-down-menu settimeout

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”或更低的位置上,菜单将关闭。如果取消注释“//alert(timeout);” B(和 A)到达那里,但超时会有一个值。为什么是这样?我认为clearTimeout会使超时变量无效?

最佳答案

您可以使用 .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变量,这设置了每个顶级的超时 <li> ,每个元素都有一个独立的计时器,当您将鼠标悬停在该元素上时,只有其计时器被清除。另外 .hover() 使用 mouseenter mouseleave ,而不是 mouseover mouseout ,区别在于当你进入一个 child 或 child 之间时,mouseenter不再触发,并且 mouseleave不会向父级开火 <li>我们关心。

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

关于jquery - 简单的 jquery 下拉菜单 -clearTimeout、setTimeout 问题,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/2316213/

相关文章:

javascript - (jQuery 插件)在多项选择测验中拖放答案

javascript - FileReader.onload无法及时返回成功

angularjs - 在 AngularJS 中使用 $timeout 代替 window.setTimeout 有什么优势?

javascript - 页面加载完成时设置超时 - jQuery

javascript - 按钮增加或减少数量 - JS

php - 类型 : Error Message: Call to a member function result() on string Filename: CI\application\models\Country_model. php 行号:34

c# - DropDownList.SelectedValue 更改(作为 FormView 中的子控件)不固定

php - 使用 PHP 填充下拉列表,不重复

html - 为什么我的下拉菜单需要点击两次才能打开?

jquery - 等待函数直到用户停止输入