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

17.2. Регистрация обработчиков событий

Существует два основных способа регистрации обработчиков событий. Первый, появившийся на раннем этапе развития Всемирной паутины, заключается в установке свойства объекта или элемента документа, являющегося целью события. Второй способ, более новый и более универсальный, заключается в передаче обработчика методу объекта или элемента. Дело осложняется тем, что каждый прием имеет две версии. Свойство обработчика события можно установить в программном коде на языке JavaScript или в элементе документа, определив соответствующий атрибут непосредственно в разметке HTML. Регистрация обработчиков вызовом метода может быть выполнена стандартным методом с именем

<b>addEventListener(),</b>
который поддерживается всеми броузерами, кроме IE версии 8 и ниже, и другим методом, с именем
<b>attachEvent(),</b>
поддерживаемым всеми версиями IE до IЕ9.

17.2.1. Установка свойств обработчиков событий

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

<b>onclick, onchange, onload, onmouseover</b>
и т. д. Обратите внимание, что эти имена свойств чувствительны к регистру и в них используются только строчные символы, даже когда имя типа события состоит из нескольких слов (например «readystatechange»). Ниже приводятся два примера регистрации обработчиков событий:

<b>// Присвоить функцию свойству onload объекта Window.</b>

<b>// Функция - обработчик события: она вызывается, когда документ будет загружен.</b>

<b>window.onload = function() {</b>

<b>  // Отыскать элемент &lt;form&gt;</b>

<b>  var elt = document.getElementById(&quot;shipping_address&quot;);</b>

<b>  // Зарегистрировать обработчик события, который будет вызываться</b>

<b>  // непосредственно перед отправкой формы.</b>

<b>  elt.onsubmit = function() { return validate(this); }</b>

<b>}</b>

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

Недостаток использования свойств обработчиков событий состоит в том, что они проектировались в предположении, что цели событий будут иметь не более одного обработчика для каждого типа событий. При создании библиотеки для использования в произвольных документах для регистрации обработчиков лучше использовать прием (такой как вызов метода

<b>addEventListener()</b>
), не изменяющий и не затирающий ранее зарегистрированные обработчики.

17.2.2. Установка атрибутов обработчиков событий

Свойства обработчиков событий в элементах документа можно также устанавливать, определяя значения атрибутов в соответствующих HTML-тегах. В этом случае значение атрибута должно быть строкой программного кода на языке JavaScript. Этот программный код должен быть не полным объявлением функции обработчика события, а только ее телом. То есть реализация обработчика события в разметке HTML не должна заключаться в фигурные скобки и предваряться ключевым словом function. Например:

<b>&lt;button onclick=&quot;alert( 'Спасибо'); &quot;Щелкните здесь&lt;/button&gt;</b>

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

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

<b>Window</b>
. В разметке HTML они должны помещаться в тег
<b>&lt;body&gt;,</b>
но броузер зарегистрирует их в объекте
<b>Window</b>
. Ниже приводится полный список таких обработчиков событий, определяемых проектом спецификации HTML5:

<b>onafterprint      onfocus        ononline     onresize</b>

<b>onbeforeprint     onhashchange   onpagehide   onstorage</b>

<b>onbeforeunload    onload         onpageshow   onundo</b>

<b>onblur            onmessage      onpopstate   onunload</b>

<b>onerror           onoffline      onredo</b>

Когда в качестве значения атрибута обработчика события в разметке HTML указывается строка с программным кодом на языке JavaScript, броузер преобразует эту строку в функцию, которая будет выглядеть примерно так:

<b>function(event) {</b>

<b>  with(document) {</b>

<b>    with(this.form || {}) {</b>

<b>      with(this) {</b>

<b>        /* ваш программный код */</b>

<b>      }</b>

<b>    }</b>

<b>  }</b>

<b>}</b>

Если броузер поддерживает стандарт ES5, функция определяется в нестрогом режиме (раздел 5.7.3). Мы еще встретимся с аргументом

<b>event</b>
и инструкциями
<b>with</b>
, когда будем рассматривать вызов обработчиков событий в разделе 17.3.

При разработке клиентских сценариев обычно принято отделять разметку HTML от программного кода на языке JavaScript. Программисты, следующие этому правилу, избегают (или, по крайней мере, стараются избегать) использовать HTML-атрибуты обработчиков событий, чтобы не смешивать программный код на языке JavaScript и разметку HTML.

17.2.3. addEventListener()

В стандартной модели событий, поддерживаемой всеми броузерами, кроме IЕ версии 8 и ниже, целью события может быть любой объект - включая объекты

<b>Window</b>
и
<b>Document</b>
и все объекты
<b>Elements</b>
элементов документа - определяющий метод с именем
<b>addEventListener()</b>
, с помощью которого можно регистрировать обработчики событий для этой цели. Метод
<b>addEventListener()</b>
принимает три аргумента. Первый - тип события, для которого регистрируется обработчик. Тип (или имя) события должен быть строкой и не должен включать префикс «on», используемый при установке свойств обработчиков событий. Вторым аргументом методу
<b>addEventListener()</b>
передается функция, которая должна вызываться при возникновении события указанного типа. В последнем аргументе методу
<b>addEventListener()</b>
передается логическое значение. Обычно в этом аргументе передается значение false. Если передать в нем значение true, функция будет зарегистрирована как перехватывающий обработчик и будет вызываться в другой фазе распространения события. Более подробно фаза перехвата событий будет рассматриваться в разделе 17.3.6. Спецификация со временем может измениться так, что будет допустимо опускать третий аргумент вместо того, чтобы явно передавать в нем значение false, но на момент написания этих строк отсутствие третьего аргумента в некоторых текущих броузерах приводила к ошибке.