所以我有一个悬停时出现的下拉导航,我正在尝试在那里延迟以提高可用性。最初我使用的是hoverIntent,除了IE8及更低版本之外,它在任何地方都运行良好。
因此,相反,我尝试使用普通的旧Javascript进行延迟,但是setTimeout函数不会调用我的jQuery。
var J = jQuery.noConflict();
J(".navigation li").hover(function(){J(this).addClass("hover");},function(){setTimeout("J(this).removeClass('hover');",500);});
当我像这样设置它时:
function off(){J(this).removeClass("hover"); alert("hello");}
J(".navigation li").hover(function(){J(this).addClass("hover");},function(){setTimeout("off()",500);});
警报工作正常,但不能使用 .removeClass 函数。
我错过了什么吗?
setTimeout
中的this
不是 li 元素;我建议您使用 setTimeout 重载来接收函数,并在将变量设置为 this
以保留引用之前:
J(".navigation li").hover(function(){
J(this).addClass("hover");
},
function(){
var self = this;
setTimeout(function() {
J(self).removeClass('hover');
},500);
});
您的off
函数:
function off() {
J(this).removeClass("hover");
alert("hello")
}
当被setTimeout()
调用时,不会有正确的this
变量 - 在大多数(所有?)浏览器上,它将this
设置为window
。
您需要一个额外的闭包来包装原始this
并将其传递给该计时器函数:
J(".navigation li").hover(
function() {
J(this).addClass("hover");
},
function() {
var that = this;
setTimeout(function() {
off.apply(that);
}, 500);
}
);
注意:不要使用字符串参数来setTimeout()
!
问题是this
指的是超时回调范围内的不同内容。
最简单的解决方案是使用 jQuery.proxy([function],[scope]) 提供旧范围
<html>
<head>
<script type="text/javascript" src="http://ajax.googleapis.com/ajax/libs/jquery/1.7.1/jquery.min.js"></script>
<script>
var f = function(){
console.log(this.id);
};
$(function() {
$("div").click(function () {
setTimeout($.proxy(f,this), 1000);
});
});
</script>
</head>
<body>
<div id="a">a</div>
<div id="b">b</div>
</body>
</html>