Статьи

JavaScript ‘this’ и обработчики событий

Если есть одна причина полагаться на библиотеку JavaScript, такую ​​как jQuery , это обработка событий. Большинство библиотек абстрагируют события в единый набор объектов и обработчиков, которые работают в большинстве современных браузеров. Но нам не нужна библиотека — мы заядлые разработчики JavaScript!

События 101

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

Ваш код JavaScript может зарегистрировать функцию-обработчик, которая срабатывает при возникновении определенного события. Большинство браузеров передают один объект в функцию, которая содержит информацию о событии, то есть какие клавиши были нажаты, положение курсора и т. Д. Затем можно выполнять определенные действия, такие как анимация элемента, выполнение Ajax-вызова или предотвращение действие браузера по умолчанию.

Кроме того, «это» может быть установлено. Обычно вы можете ожидать, что это будет элемент, который вызвал событие, но это не всегда так…

Встроенные события

Это были первые поддерживаемые браузеры обработчиков событий:

<p><a id="link" href="#" onclick="EventHandler();">click me</a></p> <script> function EventHandler() { console.log(this); } </script> 

В этом случае мы просто запускаем функцию, когда происходит событие onclick, и «this» будет глобальным объектом окна. Мы можем внести небольшие изменения в наш встроенный обработчик, чтобы элемент <a> был пропущен:

 <p><a id="link" href="#" onclick="return EventHandler(this);">click me</a></p> 

Обратите внимание, что мы также добавили «возврат». Если наш EventHandler вернет false, событие click будет отменено.

важно: никогда не используйте встроенные обработчики событий!

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

Традиционные события DOM0

Вот наш пример использования традиционной обработки событий:

 <p><a id="link" href="#">click me</a></p> <script> var link = document.getElementById("link"); link.onclick = EventHandler; function EventHandler() { console.log(this.id); } </script> 

В EventHandler () каждый браузер устанавливает «this» для элемента, который вызвал событие — нашего тега привязки. Это надежно, но имеет существенный недостаток: мы можем назначить только один обработчик для каждого типа события.

примечание: отбросьте скобки!

Будьте осторожны, чтобы не использовать link.onclick = EventHandler(); — EventHandler будет запущен немедленно, а возвращаемое значение (не определено) будет присвоено свойству onclick узла #link. Может не выдать ошибку, но ваш обработчик никогда не будет вызван, когда происходит событие click.

Современные события DOM2

Наконец, у нас есть современная обработка событий, которая позволяет указывать несколько обработчиков для одного и того же события. К сожалению, у Microsoft и W3C было несколько разногласий относительно их реализации, и только IE9 поддерживает addEventListener (). Однако мы можем использовать небольшое обнаружение объектов для создания кросс-браузерной функции присоединения к событиям, которая работает во всех браузерах:

 <p><a id="link" href="#">click me</a></p> <script> var link = document.getElementById("link"); AttachEvent(link, "click", EventHandler); function AttachEvent(element, type, handler) { if (element.addEventListener) element.addEventListener(type, handler, false); else element.attachEvent("on"+type, handler); } function EventHandler(e) { console.log(this); } </script> 

Как и в случае с DOM0, все браузеры устанавливают «this» для элемента, вызвавшего событие… кроме одного. Internet Explorer 8.0 и ниже ссылается только на обработчик событий, поэтому «this» всегда является глобальным объектом окна.

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

 function EventHandler(e) { e = e || window.event; var target = e.target || e.srcElement; console.log(target); } 

Уф. И вы удивились, почему jQuery стал таким популярным!