简单的 jquery 下拉列表 - clearTimeout、setTimeout 问题 [英] simple jquery dropdown - clearTimeout, setTimeout issues
问题描述
HTML:
<li><a href="#"><span>一个</span></a></li><li><a href="#"><span>两个</span></a></li><li><li><a href="#"><span>三</span></a></li><ul class="subnav"><li><a href="#">A</a></li><li><a href="#">B</a></li><li><a href="#">C</a></li>
jquery:
var timeout = null;$(document).ready(function() {$("ul.topnav li").mouseover(function() {如果(超时)clearTimeout(超时);$(this).find("ul.subnav").slideDown('fast').show();}).mouseout(function() {timeout = setTimeout(closemenu, 500);});//子菜单鼠标悬停保持下拉菜单打开$("ul.subnav li").mouseover(function() {如果(超时)clearTimeout(超时);}).mouseout(function() {timeout = setTimeout(closemenu, 500);//警报(超时);});//任何点击关闭$(document).click(closemenu);});//关闭所有打开的菜单函数关闭菜单(){$('ul.subnav:visible').hide();如果(超时)clearTimeout(超时);}
我遇到了超时问题.在使用中,如果我将鼠标悬停在三"上,下拉菜单将永远存在.如果我将鼠标悬停在A"上,下拉菜单将永远存在,但如果我将鼠标悬停在B"或更低的位置,菜单将关闭.如果您取消注释//alert(timeout);"它到达那里 B, (和 A) 但超时将有一个值.为什么是这样?我认为 clearTimeout 会使超时变量为空?
$(function() {$("ul.topnav li").hover(function() {var timeout = $(this).data("timeout");如果(超时)clearTimeout(超时);$(this).find("ul.subnav").slideDown('fast');}, 功能() {$(this).data("timeout", setTimeout($.proxy(function() {$(this).find("ul.subnav").slideUp();}, 这个), 500));});$(document).click(function() {$('ul.subnav:visible').hide();});});
不是共享一个全局的timeout
变量,而是设置一个超时per顶级,每个都有一个独立的定时器,当您将鼠标悬停在该元素上时,只会清除 其计时器.另外
.hover()
使用 mouseenter
和 mouseleave
,而不是 mouseover
和 mouseout
,区别在于当你进入一个孩子或者在孩子之间, mouseenter
不会再次触发,并且 mouseleave
不会在我们关心的父 上触发.
您可以使用上面的演示链接进行测试,我也在第一个菜单中添加了子项,以证明它们是独立的.如果您对那里的 $.proxy
有疑问,它只是让超时匿名函数中的 this
引用我想要的内容(当前的 this
)...超时后需要关闭的元素.>
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);
}
I'm having issues with timeout. In use, if i mouseover "Three", the dropdown stays out forever. if i mouseover "A", dropdown will stay out forever, but if I mouseover "B" or anything lower, the menu will close on me. if you uncomment "// alert(timeout);" it gets there for B, (and A) but timeout will have a value. why is this? i thought clearTimeout would null the timeout variable?
You can simplify your code overall by using .hover()
and .data()
like this:
$(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
Instead of sharing a global timeout
variable, this sets a timeout per top level <li>
, each one has an independent timer, and when you hover back over that element, only its timer is cleared. Also .hover()
uses mouseenter
and mouseleave
, rather than mouseover
and mouseout
, the difference is when you go into a child or between children, mouseenter
doesn't fire again, and mouseleave
doesn't fire on the parent <li>
we care about.
You can test this with the demo link above, I added sub-items to the first menu as well, to demonstrate they're independent. If you happen to have question about the $.proxy
in there, it's just making this
inside that timeout anonymous function refer to what I want it to (the current this
)...the element that needs closing after the timeout.
这篇关于简单的 jquery 下拉列表 - clearTimeout、setTimeout 问题的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!