2012-05-04 27 views
1

見我的代碼 http://jsfiddle.net/kxATT/3/價值這說明當事件處理程序以兩種不同的方式被分配不同的結果

  function byId(id) { 
       if (id) { 
        return document.getElementById(id); 
       } else { 
        return null; 
       } 
      } 

      function setAttr(elm, attr, value) { 
       elm.setAttribute(attr, value); 
      } 

      var app = { 
       id: 12, 
       fn: function() { 
        alert(this.id); 
       } 
      }; 

      function init() { 
       setAttr(byId('txt'), 'onclick', 'app.fn()'); 
       byId('txt1').addEventListener('click', app.fn, true); 
      } 

當點擊第一個框,它提醒12。對於第二個盒子來說,這個盒子是txt1。很顯然,在這兩種情況下,儘管我打電話的功能相同,但是this指的是不同的對象。我聽說,對於輸入元素,元素的對象本身被傳遞給函數,並在事件處理函數中作爲this進行了處理。如果是這樣,爲什麼在使用setAttribute添加事件時不是這樣。

+0

'app.fn()'....這個函數內部,'this'將參考'app'。 [在MDN上閱讀關於'this'的更多信息](https://developer.mozilla.org/en/JavaScript/Reference/Operators/this)。這是事實處理程序中的元素。嘗試'setAttr(byId('txt'),'onclick','console.log(this); app.fn()');'。字符串「app.fn()」的內容是事件處理程序的主體,所以'this'將引用該元素。但'app.fn()'只是你從事件處理函數*調用的一個函數,並且上下文永遠不會「傳送」過來(除非你使用'.call()'或'.apply()')。 –

+0

感謝您的鏈接...其新信息給我 –

回答

2

當您將字符串分配給onclick時,您基本上正在創建函數的正文;瀏覽器提供該功能,例如,您的字符串"app.fn()"變爲:

function onclickHandlerCreatedByBrowser(event) { 
    app.fn(); 
} 

當您通過addEventListener指定功能的參考,與任何時候你使用的JavaScript函數引用,它只是一個函數引用;沒有對象信息。 JavaScript中的this完全由調用函數的方式來設置,而不是它的定義位置。否則,通過提供瀏覽器提供的功能

byId('txt1').addEventListener('click', app.fn.bind(app), true); 

,你可以解決它:

如果您使用的是啓用ECMAScript5環境(或使用ES5墊片),你可以使用Function#bind解決這個在字符串中區分自己:

byId('txt1').addEventListener('click', function() { 
    app.fn(); 
}, true); 

更多閱讀:

+0

Thaks的答案和鏈接.... –

+1

+1良好的聯繫,我想我已經讀過作者的工作在某個地方...:P – alex

+0

@alex:大聲笑! ;-) –

2

this上下文是在一個事件處理程序中的對象,並在另一個input元件,其中id屬性對應於所述input元件的id屬性。

+0

感謝您回答 –

相關問題