簡體   English   中英

如何在javascript事件處理程序中獲取對象?

[英]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.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM