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

Следующий фрагмент регистрирует два обработчика события «click» в элементе

<b>&lt;button&gt;</b>
. Обратите внимание на различия двух используемых приемов:

<b>&lt;button id=&quot;mybutton''&gt;Щелкни на Mнe&lt;/button&gt;</b>

<b>&lt;script&gt;</b>

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

<b>  b.onclick = function() { </b>

<b>    alert(&quot;Спасибо, что щелкнули на мне!&quot;); </b>

<b>  };</b>

<b>  b.addEventListener(&quot;click&quot;, function() { alert(Еще раз спасибо!&quot;); }, false);</b>

<b>&lt;/script&gt;</b>

Вызов метода

<b>addEventListener()</b>
со строкой «click» в первом аргументе никак не влияет на значение свойства
<b>onclick</b>
. Во фрагменте, приведенном выше, щелчок на кнопке приведет к выводу двух диалогов
<b>alert().</b>
Но важнее то, что метод
<b>addEventListener()</b>
можно вызвать несколько раз и зарегистрировать с его помощью несколько функций-обработчиков для одного и того же типа события в том же самом объекте. При появлении события в объекте будут вызваны все обработчики, зарегистрированные для этого типа события, в порядке их регистрации. Многократный вызов метода
<b>addEventListener()</b>
для одного и того же объекта с теми же самыми аргументами не дает никакого эффекта - функция-обработчик регистрируется только один раз и повторные вызовы не влияют на порядок вызова обработчиков.

Парным к методу

<b>addEventListener()</b>
является метод
<b>removeEventListener(),</b>
который принимает те же три аргумента, но не добавляет, а удаляет функцию-обработчик из объекта. Это часто бывает удобно, когда необходимо зарегистрировать временный обработчик события, а затем удалить его в какой-то момент. Например, при получении события «mousedown» может потребоваться зарегистрировать временный перехватывающий обработчик событий «mousemove» и «mouseup», чтобы можно было наблюдать за тем, как пользователь выполняет буксировку объектов мышью, а по событию «mouseup» эти обработчики могут удаляться. В такой ситуации реализация удаления обработчиков событий может иметь вид, как показано ниже:

<b>document.removeEventListener(&quot;mousemove&quot;, handleMouseMove, true);</b>

<b>document.removeEventListener(&quot;mouseup&quot;, handleMouseUp, true);</b>

17.2.4. attachEvent()

Internet Explorer версии ниже IE9 не поддерживает методы

<b>addEventListener()</b>
и
<b>removeEventListener().</b>
В версии IE5 и выше определены похожие методы,
<b>attachEvent()</b>
и
<b>detachEvent().</b>

По своему действию методы

<b>attachEvent()</b>
и
<b>detachEvent()</b>
похожи на методы
<b>addEventListener()</b>
и
<b>removeEventListener()</b>
со следующими исключениями:

• Поскольку модель событий в IE не поддерживает фазу перехвата, методы

<b>attachEvent()</b>
и
<b>detachEvent()</b>
принимают только два аргумента: тип события и функцию обработчика.

• В первом аргументе методам в IE передается имя свойства обработчика с префиксом «on», а не тип события без этого префикса. Например, методу

<b>attachEvent()</b>
должно передаваться имя «опсііск», тогда как методу
<b>addEventListener()</b>
должно передаваться имя «click».

• Метод

<b>attachEvent()</b>
позволяет зарегистрировать одну и ту же функцию обработчика несколько раз. При возникновении события указанного типа зарегистрированная функция будет вызвана столько раз, сколько раз она была зарегистрирована.

Ниже показано, как обычно выполняется регистрация обработчика с помощью метода

<b>addEventListener() </b>
в броузерах, поддерживающих его, и с помощью метода
<b>attachEvent()</b>
в других броузерах:

<b>var b = document.getElementByldC'mybutton&quot;); </b>

<b>var handler = function() { alert(&quot;Спасибо!&quot;); }; </b>

<b>if (b.addEventListener)</b>

<b>  b.addEventListener(&quot;click&quot;, handler, false); </b>

<b>else if (b.attachEvent)</b>

<b>  b.attachEvent(&quot;onclick&quot;, handler);</b>

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

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

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

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

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

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

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

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

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