2015-02-07 36 views
3

我正在尝试设置超时与价值,看this question我发现有任何形式的setTimeout(function(), int);将“跳过”定时器,我怎么会那样对我的代码下面?值到里面的setTimeout功能

$(".addtimer div").click(function(){ 
    $(this).toggleClass("remove"); 
    setTimeout(hide(this),2000); 
}); 
function hide(name) { 
    $(name).remove(); 
} 

输出

".addtimer div" disappears instantly 

回答

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(); 
    }); 
}); 

正如你可以看到,有很多的选择,并且在使用视情况而定了一下,你觉得是什么让最清晰的代码我ñ你的情况和你最舒服的使用方式。

+0

谢谢你,知道有一个更好的办法 – Skylark 2015-02-07 17:57:35

+0

增加了其他两个选项的答案。 – jfriend00 2015-02-07 18:04:01

+0

使用var self = this;'因为他使用的是jQuery,所以我会选择['.proxy'](http://api.jquery.com/jquery.proxy/)。否则,我会使用'bind'或'closure'(我相信'proxy'用于跨浏览器的目的)。 – Xotic750 2015-02-07 18:56:34

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(); 
} 
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>

并与本地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。如果你放弃了this和使用回调的事件参数

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>

但当然,这些都不是必要的。

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>