Чтение онлайн

ЖАНРЫ

JavaScript. Подробное руководство, 6-е издание
Шрифт:
empty-line/>

17.3. Вызов обработчиков событий

После регистрации обработчика событий веб-броузер будет вызывать его автоматически, когда в указанном объекте будет возникать событие указанного типа. В этом разделе подробно описывается порядок вызова обработчиков событий, аргументы обработчиков, контекст вызова (значение

this
), область видимости и назначение возвращаемого значения обработчика. К сожалению, некоторые из этих подробностей отличаются между IE версии 8 и ниже и другими броузерами.

Кроме того, с целью описать, как вызываются отдельные обработчики событий, в этом разделе также разъясняется, как происходит распространение событий: как единственное

событие может привести к вызову нескольких обработчиков в оригинальном целевом объекте и в содержащих его элементах документа.

17.3.1. Аргумент обработчика событий

При вызове обработчика событий ему обычно (за одним исключением, о котором рассказывается ниже) передается объект события в виде единственного аргумента. Свойства объекта события содержат дополнительную информацию о событии. Свойство

type
, например, определяет тип возникшего события. В разделе 17.1 упоминалось множество других свойств объекта события для различных типов событий.

В IE версии 8 и ниже обработчикам событий, зарегистрированным установкой свойства, объект события при вызове не передается. Вместо этого объект события сохраняется в глобальной переменной

window.event
. Для переносимости обработчики событий можно оформлять, как показано ниже, чтобы они использовали переменную
window.event
при вызове без аргумента:

function handler(event) {

event = event || window.event;

// Здесь находится реализация обработчика

}

Объект события передается обработчикам событий, зарегистрированным с помощью метода

attachEvent,
но они также могут использовать переменную
window.event
.

В разделе 17.2.2 говорилось, что при регистрации обработчика события посредством HTML-атрибута броузер преобразует строку с программным кодом на языке JavaScript в функцию. Броузеры, отличные от IE, создают функцию с единственным аргументом

event
. В IE создается функция, не принимающая аргументов. Если в таких функциях использовать идентификатор
event
, он будет ссылаться на
window.event
. В любом случае обработчики событий, определяемые в разметке HTML, могут ссылаться на объект события, используя идентификатор
event
.

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
.

17.3.3. Область видимости обработчика событий

Подобно всем функциям в языке JavaScript, обработчики событий имеют лексическую область видимости. Они выполняются в той области видимости, в какой были определены, а не в той, где они были вызваны, и имеют доступ ко всем локальным переменным в этой области видимости. (Это, например, демонстрируется в функции

addEvent,
представленной выше.)

Особый случай представляют обработчики событий, которые регистрируются посредством HTML-атрибутов. Они преобразуются в функции верхнего уровня, которые не имеют доступа ни к каким локальным переменным - только к глобальным. Но по историческим причинам они выполняются в модифицированной цепочке областей видимости. Обработчики событий, определяемые посредством HTML-атрибутов, могут использовать свойства целевого объекта, объемлющего элемента

<form>
(если таковой имеется) и объекта
Document
, как если бы они были локальными переменными. В разделе 17.2.2 было показано, как из HTML-атрибута создается функция обработчика события, программный код в которой использует цепочку областей видимости, модифицированную с помощью инструкций
with
.

HTML-атрибуты плохо подходят для включения длинных строк программного кода, и такая модифицированная цепочка областей видимости помогает сократить его. Она позволяет использовать

tagName
вместо
this.tagName
,
getElementByld
вместо
document.getElementByld
, а в обработчиках, привязанных к элементам документа внутри элемента
<form>,
можно ссылаться на другие элементы формы по значению атрибута
id
, используя, например, имя
zipcode
вместо
this.form.zipcode
.

Поделиться с друзьями: