setTimeout 中函数的值
Value to a function inside a setTimeout
我正在尝试设置一个超时值,查看 this question 我发现任何形式的 setTimeout(function(), int);
都会 'skip' 计时器,我怎么会按照下面的代码执行此操作?
$(".addtimer div").click(function(){
$(this).toggleClass("remove");
setTimeout(hide(this),2000);
});
function hide(name) {
$(name).remove();
}
输出
".addtimer div" disappears instantly
由此变化:
setTimeout(hide(this),2000);
对此:
var self = this;
setTimeout(function() {
hide(self);
},2000);
您正在立即调用该函数并将其 return 值传递给 setTimeout
,而不是将函数引用传递给 setTimeout
以便稍后调用。请记住 (xx)
表示立即执行。所以 hide(this)
的意思是现在执行,而不是稍后执行。另一方面,function() { hide(this); }
是一个可以稍后调用的函数引用。
或者,如果您没有在其他任何地方使用隐藏功能,那么您可以像这样集成它:
$(".addtimer div").click(function(){
$(this).toggleClass("remove");
var self = this;
setTimeout(function() {
$(self).remove();
},2000);
});
一个有用的语言特性是 .bind()
,它可用于 "hardwire" 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();
});
});
如您所见,有很多选项,使用哪个在一定程度上取决于具体情况、您认为在您的情况下最清晰的代码以及您最习惯使用的内容。
第一个问题是您需要将一个函数传递给 setTimeout
(您没有;您正在调用该函数并将其 return 值传递给 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();
}
正如我提到的 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>
与原生 bind
function hide(name) {
$(name).remove();
}
$('.addtimer div').click(function () {
$(this).toggleClass('remove');
setTimeout(function () {
hide(this);
}.bind(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>
还有 closure
.
function hide(name) {
$(name).remove();
}
$('.addtimer div').click(function () {
$(this).toggleClass('remove');
setTimeout((function (element) {
return function () {
hide(element);
};
}(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>
当然,如果您删除 this
并使用回调的事件参数,那么 none 是必需的。
function hide(name) {
$(name).remove();
}
$('.addtimer div').click(function (e) {
$(e.target).toggleClass('remove');
setTimeout(function () {
hide(e.target);
}, 2000);
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.1/jquery.min.js"></script>
<div class="addtimer">
<div>Hello</div>
</div>
而在现代 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);
});
<div class="addtimer">
<div>Hello</div>
</div>
我正在尝试设置一个超时值,查看 this question 我发现任何形式的 setTimeout(function(), int);
都会 'skip' 计时器,我怎么会按照下面的代码执行此操作?
$(".addtimer div").click(function(){
$(this).toggleClass("remove");
setTimeout(hide(this),2000);
});
function hide(name) {
$(name).remove();
}
输出
".addtimer div" disappears instantly
由此变化:
setTimeout(hide(this),2000);
对此:
var self = this;
setTimeout(function() {
hide(self);
},2000);
您正在立即调用该函数并将其 return 值传递给 setTimeout
,而不是将函数引用传递给 setTimeout
以便稍后调用。请记住 (xx)
表示立即执行。所以 hide(this)
的意思是现在执行,而不是稍后执行。另一方面,function() { hide(this); }
是一个可以稍后调用的函数引用。
或者,如果您没有在其他任何地方使用隐藏功能,那么您可以像这样集成它:
$(".addtimer div").click(function(){
$(this).toggleClass("remove");
var self = this;
setTimeout(function() {
$(self).remove();
},2000);
});
一个有用的语言特性是 .bind()
,它可用于 "hardwire" 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();
});
});
如您所见,有很多选项,使用哪个在一定程度上取决于具体情况、您认为在您的情况下最清晰的代码以及您最习惯使用的内容。
第一个问题是您需要将一个函数传递给 setTimeout
(您没有;您正在调用该函数并将其 return 值传递给 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();
}
正如我提到的 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>
与原生 bind
function hide(name) {
$(name).remove();
}
$('.addtimer div').click(function () {
$(this).toggleClass('remove');
setTimeout(function () {
hide(this);
}.bind(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>
还有 closure
.
function hide(name) {
$(name).remove();
}
$('.addtimer div').click(function () {
$(this).toggleClass('remove');
setTimeout((function (element) {
return function () {
hide(element);
};
}(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>
当然,如果您删除 this
并使用回调的事件参数,那么 none 是必需的。
function hide(name) {
$(name).remove();
}
$('.addtimer div').click(function (e) {
$(e.target).toggleClass('remove');
setTimeout(function () {
hide(e.target);
}, 2000);
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.1/jquery.min.js"></script>
<div class="addtimer">
<div>Hello</div>
</div>
而在现代 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);
});
<div class="addtimer">
<div>Hello</div>
</div>