17.3.2. Контекст обработчиков событий
Когда обработчик событий регистрируется установкой свойства, это выглядит как определение нового метода элемента документа:
e.onclick = function() { /* реализация обработчика */ };
Поэтому нет ничего удивительного, что обработчики событий вызываются (с одним исключением, касающимся IE, которое описывается ниже) как методы объектов, в которых они определены. То есть в теле обработчика событий ключевое слово this ссылается на цель события.
В обработчиках ключевое слово this ссылается на целевой объект, даже когда они были зарегистрированы с помощью метода addEventListener(). Однако, к сожалению, это не относится к методу attachEvent(): обработчики, зарегистрированные с помощью метода attachEvent(), вызываются как функции, и в них ключевое слово this ссылается на глобальный (Window) объект. Эту проблему можно решить следующим способом:
/*
* Регистрирует указанную функцию как обработчик событий указанного типа в указанном
* объекте. Гарантирует, что обработчик всегда будет вызываться как метод целевого объекта.
*/
function addEvent(target, type, handler) {
if (target.addEventListener)
target.addEventListener(type, handler, false);
else
target.attachEvent(“on" + type,
function(event) {
// Вызвать обработчик как метод цели,
// и передать ему объект события
return handler.call(target, event);
});
}
Обратите внимание, что обработчики событий, зарегистрированные таким способом, нельзя удалить, потому что ссылка на функцию-обертку, передаваемую методу attachEvent(), нигде не сохраняется, чтобы ее можно было передать методу detachEvent().