setTimeout()和设置参数
我有一些 jQuery 代码,如下所示:
$('.mainNav2 > li').mouseleave(function(){
var someNum = Math.random();
$(this).attr('id', someNum);
var t = setTimeout("HideMenu(someNum)", 200);
$('li.clicked').mouseenter(function() {
clearTimeout(t);
});
});
function HideMenu(id) {
$('#'+id).removeClass('clicked');
}
它的目的是在鼠标离开时隐藏大型菜单,但也通过使用 300 毫秒的 setTimeout 考虑鼠标意外离开。如果用户在 300 毫秒内将鼠标指针移回到 li 中,则菜单不会隐藏,因为调用了clearTimout(t)。
问题是当用户确实想要鼠标移出时,setTimout 中的函数不会被调用。根据此页面: http://www.w3schools.com/js/js_timing.asp 我的语法是正确的,但如果我这样写,我只能从 setTimeout 调用 HideMenu 函数:
var t = setTimeout(HideMenu, 300);
为什么它不能按编写的方式工作,我可以将变量作为参数传递到函数中?
I have some jQuery code that looks like this:
$('.mainNav2 > li').mouseleave(function(){
var someNum = Math.random();
$(this).attr('id', someNum);
var t = setTimeout("HideMenu(someNum)", 200);
$('li.clicked').mouseenter(function() {
clearTimeout(t);
});
});
function HideMenu(id) {
$('#'+id).removeClass('clicked');
}
It's purpose is to hide a mega menu on mouse leave, but also takes into account accidental mouse leaves, by using a 300 millisecond setTimeout. If the user brings the mouse pointer back into the li within 300 milliseconds, the menu is not hidden because clearTimout(t) is called.
The problem is when the user DOES intent to mouseout, the function in the setTimout is not being called. According to this page: http://www.w3schools.com/js/js_timing.asp my syntax is correct, but I can only get the HideMenu function called from the setTimeout if I write it like this:
var t = setTimeout(HideMenu, 300);
Why isn't it working as written, where I can pass a variable into the function as a parameter?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(7)
虽然标记的正确答案是实现这一目标的一种方法......但我不认为这是正确的。
请参阅附件 JS Fiddle:
http://jsfiddle.net/PWHw3/
我们在这里所做的基本上是:
示例:
这对我有用,并且消除了传递两个函数的需要。
While the marked correct answer is one method of achieving this... I don't believe it is the correct.
See the attached JS Fiddle:
http://jsfiddle.net/PWHw3/
What we are doing here basically is:
Example:
This works for me, and eliminates the needs to pass through two functions.
为了使其工作,并且在不使用 setTimeout 的令人讨厌的 eval 版本的情况下进行更改:
改为:
这样,您可以将
someNum
的值传递到作用域中的变量s
中setTimeout
的。To make it work, and do it without using the nasty eval version of setTimeout change:
to this:
This way you pass the value of
someNum
into the variables
in the scope of thesetTimeout
.setTimeout
接受一个函数和毫秒延迟。该函数可以是函数引用,也可以是在超时触发时进行计算的字符串。您当前的序列如下所示:mouseleave 函数
someNum
分配一个值。 someNum 的范围为当前函数
“HideNum(someNum)”
。200ms 传递
"HideNum(someNum)"
被评估。它应该抛出异常,因为变量 someNum 未定义。这就是为什么 HideNum 没有被调用 - 检查控制台中的错误。你想要的是一个函数引用,它将把你的 someNum 保持在范围内(通过闭包 - 你可能想阅读)。
您会发现 Mozilla 文档是 JavaScript 的更好参考。这是 window.setTimeout 文档。
setTimeout
accepts a function and a millisecond delay. The function can be either a function reference or a string that will get evaluated when the timeout fires. Your current sequence looks like this:mouseleave function
someNum
a value. someNum is scoped tothe current function
"HideNum(someNum)"
after 200ms.200ms passes
"HideNum(someNum)"
is evaluated. It should throw an exception as the variable someNum is undefined. That's why HideNum is not being called - check for errors in your console.What you want is a function reference, which will keep your someNum in scope (via closure - which you might want to read up on).
You'll find the Mozilla docs a better reference for JavaScript. Here's the window.setTimeout docs.
您想要做的是创建一个匿名函数并在 setTimeout 调用中调用它。
不过,如果我正确理解你想要做什么,你就不必费心设置 id 之类的东西。像这样的事情应该这样做:
What you want to do is to create an anonymous function and call that in the setTimeout call.
If I correctly understand what you want to do, though, you shouldn't have to bother with setting an id and all that stuff. Something like this should do it:
还有更多方法可以做到这一点。
1. 使用匿名函数(推荐)
2.
setTimeout
和setInterval
有一个隐藏功能:可以指定超时后的参数。由于您已经在使用 jQuery,因此您不应该创建一个单独的函数,而应该扩展 jQuery 的原型,如下所示:
用法:
请注意,当您执行以下操作时,不需要将
this
传递给 jQuery正在扩展它的原型,因为它已经传递给了 jQuery。并且需要return this;
来保持链接的能力。如果你选择这种方式,你需要使用匿名函数,没有更简单的方法了。
更新
已经有一个插件:
jQuery.hoverIntent()
< /a>.无需自己制作。它很容易使用,只需将mouseleave
事件替换为:这样做很重要,因为第一个是
mouseenter
处理程序,第二个是>mouseleave
处理程序。jQuery.noop
是一个空函数,它实际上与function() {}
相同。There are more ways to do that.
1. Use an anonymous function (recommended)
2.
setTimeout
andsetInterval
have a hidden feature: you can specify parameters after the timeout.Since you're already using jQuery, you shouldn't make a separate function, but extend jQuery's prototype instead, like this:
Usage:
Notice that you don't need to pass
this
to jQuery when you're extending its prototype, because it's already passed to jQuery. Andreturn this;
is required to keep the ability of chaining.If you choose this way, you need to use an anonymous functions, there's no easier way.
Update
There's already a plugin for that:
jQuery.hoverIntent()
. No need to make it yourself. It's easy to use, just replacemouseleave
event with this:It's important to do it this way, since the first one is the
mouseenter
handler, and the second is themouseleave
handler.jQuery.noop
is an empty function, it's effectively the same asfunction() {}
.这有效,并且也可以在循环中使用。
This works, and can be used within a loop also.
因为你正在编写一个字符串,它并不像实际的闭包那么智能。
Because you're writing a string, which isn't as intelligent as an actual closure.