setTimeout中函数的值

时间:2015-02-07 17:52:12

标签: javascript settimeout

我正试着用一个值设置一个超时,看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

3 个答案:

答案 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;
&#13;
&#13;

使用原生bind

&#13;
&#13;
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;
&#13;
&#13;

并使用closure

&#13;
&#13;
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;
&#13;
&#13;

但是当然,如​​果删除this并使用回调的事件参数,则不需要这样做。

&#13;
&#13;
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;
&#13;
&#13;

在现代ECMA5中

&#13;
&#13;
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;
&#13;
&#13;