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
这不是共享全局超时变量,而是设置每个顶级超时< li>的超时,每个都有一个独立的计时器,当您将鼠标悬停在该元素上时,只清除其计时器.另外.hover()
使用mouseenter
和mouseleave
,而不是mouseover
和mouseout
,区别在于当你进入孩子或孩子之间时,mouseenter不会再次开火,而且mouseleave不会在父母< li>上开火.我们关心.
您可以使用上面的演示链接对此进行测试,我也将子项添加到第一个菜单中,以证明它们是独立的.如果你碰巧在那里有关于$.proxy
的问题,它只是在内部超时匿名函数引用我想要它(当前这个)…在超时后需要关闭的元素.