[英]How can I get an object inside a javascript event handler?
我試圖在onclick事件處理函數中獲取一個對象。
但它並沒有像我期望的那樣發揮作用。
例如,如果我運行此代碼:
var entries = [{id: 1},{id: 2},{id: 3}];
for (var i = 0; i < entries.length; i++) {
var entry = entries[i];
document.getElementById(entry.id).onclick = function () {
console.log("this.id: " + this.id);
console.log("entry.id: " + entry.id);
};
}
我的期望是:
this.id: 1
entry.id: 1
this.id: 2
entry.id: 2
this.id: 3
entry.id: 3
但我得到的是:
this.id: 1
entry.id: 3
this.id: 2
entry.id: 3
this.id: 3
entry.id: 3
為什么條目對象始終是id為3的條目?
如何在click事件處理程序中獲取正確的條目對象?
解決此問題的一種方法是:
var entries = [{id: 1},{id: 2},{id: 3}];
for (var i = 0; i < entries.length; i++) {
var entry = entries[i];
document.getElementById(entry.id).onclick = (function (id) {
return function () {
console.log("this.id: " + this.id);
console.log("entry.id: " + id);
};
})(entry.id);
}
您可以使用自執行函數(其目的是提供entry.id將綁定的閉包)來返回綁定到特定id的新onclick處理程序。
如果不這樣做,所有onclick處理程序都綁定到相同的條目變量,並以for循環期間收到的最后一個值結束。
這是關閉的棘手問題之一。 您正在創建的事件處理程序具有關閉了entry
。 他們都可以訪問該變量,即確切的變量。 因此,一旦這些事件觸發,它們只會獲得設置為最后一個值。 你需要打破關閉。 這是一種方式。
function addClickHandlers() {
var entries = [{id: 1},{id: 2},{id: 3}];
var i = entries.length;
while (i--) {
var entry = entries[i];
document.getElementById(entry.id).onclick = getClickHandler(entry);
}
}
function getClickHandler(entry) {
return function() {
console.log("this.id: " + this.id);
console.log("entry.id: " + entry.id);
};
}
注意:我將for循環更改為一段時間只是因為當訂單不重要時,這是在javascript中循環的最快方式,我認為它很光滑。
還有一些其他方法可以解決這種情況。 我發現我一直都在使用它們。
在Ext中有createDelegate
myhandler.createDelegate(scope, [arguments], [appendArgs]);
對於javascript 1.8.5,有Function.prototype.bind
myhandler.bind(scope, arguments)
編寫Function.prototype.bind非常簡單( 從這里解除 )
Function.prototype.bind = function(self, var_args) {
var thisFunc = this;
var leftArgs = Array.slice(arguments, 1);
return function(var_args) {
var args = leftArgs.concat(Array.slice(arguments, 0));
return thisFunc.apply(self, args);
};
};
這是因為閉包在JavaScript中的工作方式。 所有3個元素的onclick引用存儲相同的函數,該函數在循環后具有指向最后一個條目的條目。 因此結果。 您可以通過將其包裝到具有所需條目的另一個函數中來獲得結果。 以下是一種方法:
var entries = [{id: 1},{id: 2},{id: 3}];
for (var i = 0; i < entries.length; i++) {
var entry = entries[i];
function setOnClickHandler(entry) {
document.getElementById(entry.id).onclick = function () {
console.log("this.id: " + this.id);
console.log("entry.id: " + entry.id);
};
}
setOnClickHandler(entry);
}
我已經寫了一個小哨此 。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.