2012-05-04 1 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'. [Подробнее о 'this' на MDN] (https://developer.mozilla.org/en/JavaScript/Reference/Operators/this). Это правда, что '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, это просто функцией ссылки; нет информации об объекте. this в JavaScript полностью определяется тем, как вызывается функция, а не там, где она определена.

Если вы используете среду ECMAScript5 поддержки (или с помощью ES5 подкладку), вы можете решить эту проблему с помощью Function#bind:

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

В противном случае, вы можете решить, предоставляя функции, что браузер предоставляет в подстроки себя:

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

Больше чтение:

+0

Спасибо за ответ и ссылки .... –

+1

+1 Хорошие ссылки, я думаю, что я читал эту работу автора где-то ...: P – alex

+0

@alex: LOL! ;-) –

2

this контекст является объектом в одном обработчика событий и input элемента в другой, из которых id свойство соответствует атрибуту input элемента id.

+0

Спасибо, что ответили –