Javascript.RU

Сравнение способов добавления обработчиков

В статье приводится сравнение способов добавления обработчиков через on(click), addEventListener и attachEvent.

Рассмотрены особенности, плюсы и минусы разных способов.

Считается, что вы знакомы с основными свойствами объекта события и порядком их обработки.

Самый универсальный метод. У него есть, пожалуй, только один существенный недостаток: можно повесить лишь один обработчик.

Кроме того, есть глюк с iframe: в Firefox не будет работать обработчик, назначенный так:

iframeElement.onclick = function(event) { .... }

Но будет прекрасно работать addEventListener:

iframeElement.addEventListener( "click", ... )
  1. Полная кросс-браузерность
  2. Только один обработчик на событие
  3. Глюк с iframe в браузерах от Mozilla

Методы attachEvent/addEventListener имеют ряд общих недостатков.

Во-первых, ни W3C ни Microsoft не определяют порядок срабатывания обработчиков. Несколько обработчиков одного события на элементе могут сработать в любом порядке.

На момент написания статьи addEventListener сохранял порядок назначения обработчиков, а attachEvent в IE выполнял обработчики в обратном порядке. Но это недокументированое и, возможно, ненадежное поведение.

elem.attachEvent("onclick", handler);
elem.attachEvent("onclick", handler2);
// может быть так, что handler2 сработает раньше handler. 
// так, судя по демке ниже, ведет себя IE.
// а может быть, handler сработает раньше handler2.
// так в демо ниже ведет себя Opera
// ... вообще, порядок неопределен

На одну и ту же кнопку вешаются два обработчика onclick: первый выдает "1", второй выдает "2".

Есть еще одна проблема, с которой можно столкнуться при управлении событиями: нельзя точно сказать установлен ли определённый обработчик, или нет, и какие обработчики установлены на данный момент.

В спецификации DOM 3 существует объект eventListenerList, но он слишком новый и на данный момент не поддерживается ни одним из браузеров.

Обработчик ставится как:

element.attachEvent( "on"+имя_события, обработчик)

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

Значение this указывает на window, а свойство event.currentTarget отсутствует.

И это достаточно важная особенность!

Например, пусть мы хотим подсвечивать divElem при клике.

Элемент divElem с разным текстом и различными ссылками, и даже с жирным текстом внутри тага <b>

Конечно, же мы повесим обработчик на divElem:

divElem.attachEvent("onclick", handler)

Но при клике из объекта события event в IE можно получить только srcElement, то есть самый глубокий кликнутый элемент. Он может быть ссылкой <a> или элементом <b>, но нам-то нужны не они, а сам divElem, чтобы его подсветить.

Обработчик, добавленный при помощи attachEvent никак не может выяснить объект, на который подвешен.

Впрочем, это легко обойти при помощи небольшого замыкания, корректно передающего указатель this:

divElem.attachEvent("onclick", function() { handler.call(divElem) })

Но этот код порождает утечку памяти в Internet Explorer 6, на который не установлено исправляющее обновление, вышедшее в июне 2007 года, из-за круговой ссылки DOM <-> JS.

  • Можно повесить несколько обработчиков на одно событие
  • Не передается текущий элемент.
  • Поддерживается только IE/Opera.

Решение W3C работает во всех современных браузерах, кроме Internet Explorer.

Установка обработчика:

element.addEventListener( имя_события, обработчик, фаза)

Пожалуй, особенных недостатков, кроме общих с attachEvent, у этого способа нет.

  • Можно повесить несколько обработчиков на одно событие
  • Умеет вешать обработчики на фазу погружения события
  • Стандарт W3C
  • Не поддерживается IE.

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


Автор: Misha_White, дата: 25 февраля, 2010 - 07:57
#permalink

А как удалить свой пост?


Автор: thunder2, дата: 28 февраля, 2010 - 00:53
#permalink

Никак ! Мучайся теперь всю жизнь !


Отправить комментарий

Приветствуются комментарии:
  • Полезные.
  • Дополняющие прочитанное.
  • Вопросы по прочитанному. Именно по прочитанному, чтобы ответ на него помог другим разобраться в предмете статьи.
    Для остальных вопросов и обсуждений есть форум.
P.S. Лучшее "спасибо" - не комментарий, как все здорово, а рекомендация или ссылка на статью.
Содержание этого поля является приватным и не предназначено к показу.
  • Адреса страниц и электронной почты автоматически преобразуются в ссылки.
  • Разрешены HTML-таги: <strike> <a> <em> <strong> <cite> <code> <ul> <ol> <li> <dl> <dt> <dd> <u> <i> <b> <pre> <img> <abbr> <blockquote> <h1> <h2> <h3> <h4> <h5> <p> <div> <span> <sub> <sup>
  • Строки и параграфы переносятся автоматически.
  • Текстовые смайлы будут заменены на графические.

Подробнее о форматировании

CAPTCHA
Антиспам
4 + 1 =
Введите результат. Например, для 1+3, введите 4.
 
Текущий раздел
Поиск по сайту
Содержание

Учебник javascript

Основные элементы языка

Сундучок с инструментами

Интерфейсы

Все об AJAX

Оптимизация

Разное

Дерево всех статей

Статьи и мероприятия

Будьте в курсе наших последних новостей!

Ответьте, пожалуйста..
О чем бы вы хотели услышать на конференции по javascript?

На какие темы послушать доклады? Конференция состоится в середине мая.


Последние обсуждения на форуме
Forum
Последние комментарии