JavaScript. Подробное руководство, 6-е издание, стр. 256

17.3.4. Возвращаемые значения обработчиков

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

<b>onclick</b>
кнопки отправки формы может вернуть false, чтобы предотвратить отправку формы броузером. (Это может пригодиться, если ввод пользователя не прошел проверку на стороне клиента.) Аналогично обработчик события
<b>onkeypress</b>
поля ввода может фильтровать ввод с клавиатуры, возвращая false при вводе недопустимых символов. (Пример 17.6 фильтрует ввод с клавиатуры именно таким способом.)

Также важно значение, возвращаемое обработчиком

<b>onbefоreunload</b>
объекта
<b>Window</b>
. Это событие генерируется, когда броузер выполняет переход на другую страницу. Если этот обработчик вернет строку, она будет выведена в модальном диалоге, предлагающем пользователю подтвердить свое желание покинуть страницу.

Важно понимать, что учитываются значения, возвращаемые обработчиками событий, только если обработчики зарегистрированы посредством установки свойств. Далее мы увидим, что обработчики, зарегистрированные с помощью

<b>addEventListener()</b>
или
<b>attachEvent()</b>
вместо этого должны вызывать метод
<b>preventDefault()</b>
или устанавливать свойство
<b>returnValue</b>
объекта события.

17.3.5. Порядок вызова

Для элемента документа или другого объекта можно зарегистрировать более одного обработчика одного и того же типа события. При возникновении этого события броузер вызовет все обработчики в порядке, определяемом следующими правилами:

• В первую очередь вызываются обработчики, зарегистрированные установкой свойства объекта или с помощью HTML-атрибута, если таковые имеются.

• Затем вызываются обработчики, зарегистрированные с помощью метода addEventListener(), в порядке их регистрации. [45]

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

<b>attachEvent(),</b>
могут вызываться в произвольном порядке, поэтому ваши сценарии не должны полагаться на какой-то определенный порядок.

17.3.6. Распространение событий

Когда целью события является объект

<b>Window</b>
или какой-то другой самостоятельный объект (такой как
<b>XMLHttpRequest</b>
), броузер откликается на событие простым вызовом соответствующего обработчика в этом объекте. Однако когда целью события является объект
<b>Document</b>
или элемент
<b>Element</b>
документа, ситуация несколько осложняется.

После вызова обработчиков событий, зарегистрированных в целевом элементе, большинство событий «всплывают» вверх по дереву DOM. В результате вызываются обработчики в родителе целевого элемента. Затем вызываются обработчики, зарегистрированные в родителе родителя целевого элемента. Так продолжается, пока не будет достигнут объект

<b>Document</b>
и затем объект
<b>Window</b>
. Способность событий всплывать обеспечивает возможность реализации альтернативы множеству обработчиков, зарегистрированных в отдельных элементах документа: можно зарегистрировать единственный обработчик в общем элементе-предке и обрабатывать события в нем. Например, вместо того чтобы регистрировать обработчик события «change» в каждом элементе формы, его можно зарегистрировать в единственном элементе
<b>&lt;form&gt;</b>
.

Способностью всплывать обладает большинство событий, возникающих в элементах документа. Заметным исключением являются события «focus», «blur» и «scroll». Событие «load», возникающее в элементах, также всплывает, но оно прекращает всплывать в объекте

<b>Document</b>
и не достигает объекта
<b>Window</b>
. Событие «load» в объекте
<b>Window</b>
возбуждается, только когда будет загружен весь документ.

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

<b>addEventListener()</b>
имеет третий аргумент, в котором принимает логическое значение. Если передать в этом аргументе значение true, обработчик события будет зарегистрирован как перехватывающий обработчик для вызова в первой фазе распространения события. Фаза всплытия событий реализована во всех броузерах, включая IE, и в ней участвуют все обработчики, независимо от того, как они были зарегистрированы (если только они не были зарегистрированы как перехватывающие обработчики). В фазе перехвата, напротив, участвуют только обработчики, зарегистрированные с помощью метода
<b>addEventListener(),</b>
когда в третьем аргументе ему было передано значение true. Это означает, что фаза перехвата событий недоступна в IE версии 8 и ниже, и на момент написания этих строк имела ограничения в использовании.

Фаза перехвата напоминает фазу всплытия, только событие распространяется в обратном направлении. В первую очередь вызываются перехватывающие обработчики объекта

<b>Window</b>
, затем вызываются перехватывающие обработчики объекта
<b>Document</b>
, затем обработчики объекта
<b>body</b>
и так далее, вниз по дереву DOM, пока не будут вызваны перехватывающие обработчики родителя целевого объекта. Перехватывающие обработчики, зарегистрированные в самом целевом объекте, не вызываются.

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

17.3.7. Отмена событий

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

<b>addEventListener(),</b>
отменить выполнение действий по умолчанию можно также вызовом метода
<b>рreventDefault()</b>
объекта события. Однако в IE, версии 8 и ниже, тот же эффект достигается установкой свойства
<b>returnValue</b>
объекта события в значение false. В следующем фрагменте демонстрируется обработчик вымышленного события, который использует все три способа отмены события: