我有一些看起来像这样的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)。
问题是当用户意图使用mouseout时,不会调用setTimout中的函数。根据这个页面:http://www.w3schools.com/js/js_timing.asp我的语法是正确的,但如果我这样写的话,我只能从setTimeout中调用HideMenu函数:
var t = setTimeout(HideMenu, 300);
为什么它不能像写入一样工作,我可以将变量作为参数传递给函数?
答案 0 :(得分:13)
要使它工作,并且不使用令人讨厌的eval版本的setTimeout更改:
var t = setTimeout("HideMenu(someNum)", 200);
到此:
var t = setTimeout(function(s) {
return function() { HideMenu(s) } }(someNum), 200);
这样您就可以将someNum
的值传递到s
范围内的变量setTimeout
。
答案 1 :(得分:3)
setTimeout
接受函数和毫秒延迟。该函数可以是函数引用,也可以是在超时触发时进行评估的字符串。您当前的序列如下所示:
mouseleave功能
someNum
指定一个值。 someNum的范围是
当前的功能"HideNum(someNum)"
。200ms通过
"HideNum(someNum)"
。它应该抛出一个异常,因为变量someNum是未定义的。这就是为什么不调用HideNum的原因 - 检查控制台中的错误。你想要的是一个函数引用,它将你的someNum保持在范围内(通过闭包 - 你可能想要阅读它)。
setTimeout(function() {
HideNum(someNum);
}, 200);
您会发现Mozilla文档是JavaScript的更好参考。这是window.setTimeout文档。
答案 2 :(得分:2)
您要做的是创建一个匿名函数并在setTimeout调用中调用它。
setTimeout(function() { HideMenu(someNum) }, 200);
如果我正确理解你想做什么,你不应该为设置id和所有东西而烦恼。这样的事情应该这样做:
$('.mainNav2 > li').mouseleave(function() {
var $this = $(this);
var t = setTimeout(function() {
$this.removeClass('clicked');
}, 200);
$('li.clicked').mouseenter(function() {
clearTimeout(t);
});
});
答案 3 :(得分:1)
还有更多方法可以做到这一点。
1。使用匿名函数(推荐)
setTimeout(function() {
hideMenu('someNum');
}, 200);
2。 setTimeout
和setInterval
具有隐藏功能:您可以在超时后指定参数。
setTimeout(hideMenu, 200, params);
由于你已经在使用jQuery,你不应该创建一个单独的函数,而是扩展jQuery的原型,如下所示:
jQuery.fn.hideMenu = function() {
this.removeClass('clicked');
return this;
};
用法:
$('#num').hideMenu();
请注意,在扩展原型时,您不需要将this
传递给jQuery,因为它已经传递给jQuery。并且return this;
需要保持链接的能力。
如果选择这种方式,则需要使用匿名函数,没有更简单的方法。
已有一个插件:jQuery.hoverIntent()
。无需亲自制作。它易于使用,只需将mouseleave
事件替换为:
$('#someNum').hoverIntent(jQuery.noop, function() {
// your function goes here
});
这样做非常重要,因为第一个是mouseenter
处理程序,第二个是mouseleave
处理程序。 jQuery.noop
是一个空函数,它实际上与function() {}
相同。
答案 4 :(得分:1)
这个工作,也可以在循环中使用。
var x = "OK";
setTimeout(alertOK.bind(null,x), 3000);
x = "Would be WRONG";
console.log("before timeout:", x);
function alertOK(x){
console.log("after timeout:",x);
}
答案 5 :(得分:0)
因为你正在写一个字符串,它不像实际的闭包那样聪明。
$('.mainNav2 > li').mouseleave(function(){
var someNum = Math.random();
$(this).attr('id', someNum);
var t = setTimeout(function() { HideMenu(someNum); }, 200);
$('li.clicked').mouseenter(function() {
clearTimeout(t);
});
});
function HideMenu(id) {
$('#'+id).removeClass('clicked');
}