我正试着用一个值设置一个超时,看this question我发现任何形式的setTimeout(function(), int);
都会'跳过'计时器,我怎么做到我的代码如下?
$(".addtimer div").click(function(){
$(this).toggleClass("remove");
setTimeout(hide(this),2000);
});
function hide(name) {
$(name).remove();
}
输出
".addtimer div" disappears instantly
答案 0 :(得分:4)
从此改变:
setTimeout(hide(this),2000);
到此:
var self = this;
setTimeout(function() {
hide(self);
},2000);
您正在立即调用该函数并将其返回值传递给setTimeout
,而不是将函数引用传递给稍后可以调用的setTimeout
。请记住,(xx)
表示立即执行。所以hide(this)
意味着现在执行它,而不是更晚。另一方面,function() { hide(this); }
是一个可以在以后调用的函数引用。
或者,如果你没有在其他任何地方使用隐藏功能,那么你可以像这样整合它:
$(".addtimer div").click(function(){
$(this).toggleClass("remove");
var self = this;
setTimeout(function() {
$(self).remove();
},2000);
});
一个有用的语言功能是.bind()
,它可以用来“硬连接”this
或回调函数参数的值。例如,您可以这样做:
$(".addtimer div").click(function(){
$(this).toggleClass("remove");
setTimeout(function() {
$(this).remove();
}.bind(this),2000);
});
调用回调函数时,.bind(this)
将this
的当前值设置为this
的值。
或者,如果您仍然使用函数hide(item)
,那么您可以使用.bind将参数设置为hide()
,如下所示:
$(".addtimer div").click(function(){
$(this).toggleClass("remove");
setTimeout(hide.bind(null, this)), 2000);
});
或者,您可以使用动画并让它为您提供时间:
$(".addtimer div").click(function(){
$(this).toggleClass("remove").delay(1000).slideUp(1000, function() {
$(this).remove();
});
});
正如您所看到的,有很多选项和使用方法取决于具体情况,您认为在您的情况下最清晰的代码以及您最适合使用的内容。
答案 1 :(得分:4)
第一个问题是你需要将一个函数传递给setTimeout
(你没有;你正在调用函数并将其返回值传递给setTimeout
),第二个问题是你需要正确处理this
。
有两种主要方法可以使this
处理正确。
使用.bind()
:
$(".addtimer div").click(function(){
$(this).toggleClass("remove");
// you could also use function () { hide(this); }.bind(this)
setTimeout(hide.bind(null, this), 2000);
});
function hide(name) {
$(name).remove();
}
或使用别名变量:
$(".addtimer div").click(function(){
$(this).toggleClass("remove");
var self = this;
setTimeout(function () { hide(self) }, 2000);
});
function hide(name) {
$(name).remove();
}
还有一个选择是完全不使用this
并使用e.target
(因为这是一个jQuery DOM事件处理程序):
$(".addtimer div").click(function (e){
$(e.target).toggleClass("remove");
setTimeout(function () { hide(e.target) }, 2000);
});
function hide(name) {
$(name).remove();
}
答案 2 :(得分:0)
正如我提到的jQuery' .proxy
,我认为最好举个例子。
function hide(name) {
$(name).remove();
}
$('.addtimer div').click(function () {
$(this).toggleClass('remove');
setTimeout($.proxy(function () {
hide(this);
}, this), 2000);
});

<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.1/jquery.min.js"></script>
<div class="addtimer">
<div>Hello</div>
</div>
&#13;
使用原生bind
function hide(name) {
$(name).remove();
}
$('.addtimer div').click(function () {
$(this).toggleClass('remove');
setTimeout(function () {
hide(this);
}.bind(this), 2000);
});
&#13;
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.1/jquery.min.js"></script>
<div class="addtimer">
<div>Hello</div>
</div>
&#13;
并使用closure
。
function hide(name) {
$(name).remove();
}
$('.addtimer div').click(function () {
$(this).toggleClass('remove');
setTimeout((function (element) {
return function () {
hide(element);
};
}(this)), 2000);
});
&#13;
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.1/jquery.min.js"></script>
<div class="addtimer">
<div>Hello</div>
</div>
&#13;
但是当然,如果删除this
并使用回调的事件参数,则不需要这样做。
function hide(name) {
$(name).remove();
}
$('.addtimer div').click(function (e) {
$(e.target).toggleClass('remove');
setTimeout(function () {
hide(e.target);
}, 2000);
});
&#13;
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.1/jquery.min.js"></script>
<div class="addtimer">
<div>Hello</div>
</div>
&#13;
在现代ECMA5中
function hide(name) {
name.parentNode.removeChild(name);
}
[].forEach.call(document.querySelectorAll('.addtimer div'), function (item) {
item.addEventListener('click', function (e) {
e.target.classList.toggle('remove');
setTimeout(function () {
hide(e.target);
}, 2000);
}, false);
});
&#13;
<div class="addtimer">
<div>Hello</div>
</div>
&#13;