2015-02-07 56 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>