JavaScript - Способы подписки на события. JavaScript - Способы подписки на события Использование атрибута HTML

У вас есть следующий прослушиватель для клавиатуры ArrowDown event (it key code is 40):

Window.onload = function() { var itemsContainer = document.getElementById("cities-drop"); document.addEventListener("*****",function(event){ if (event.keyCode == 40 && itemsContainer.style.display=="block") { event.preventDefault(); for (var i=0;i

в этом случае hovering переходит к последнему элементу в списке, после нажатия ArrowDown .

В случае, если break раскоментирован, он переходит ко второму элементу и больше не прыгает.

Невозможно получить принцип, как это сделать, что слушатель всегда слушает...

ИЗМЕНИТЬ живая демонстрация возможно, это вопрос закрытия, но я не уверен, что

3 ответа

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

If (itemsContainer.getAttribute("class").indexOf("hovered") != -1) Подробнее: Фактически вы использовали substr со строковым значением для индекса start . Не уверен, каков был бы результат этого, но, по-видимому, это не -1, поскольку условие возвращалось true каждый раз, заставляя следующий элемент зависеть КАЖДОЕ время, вплоть до нижней части списка. С помощью инструкции break в ней выполнялся оператор if в первом элементе (заставляя второй элемент "зависать"), а затем завершался.

Я оставил бы инструкцию break там, после исправления вашего кода, так что цикл остановится после того, как он найдет его совпадение, и не будет излишне перебирать остальные элементы.

EDIT:

Я нашел еще пару проблем в коде. Вот пример, который работает для меня в IE и FF, по крайней мере (не тестировался в Safari, Opera или Chrome):

Подробно: Для меня в IE9 функция никогда не вызывалась. Вместо этого я просто сделал его регулярной функцией и добавил событие onkeydown в тег body .

В вашем if-statement у вас есть itemsContainer.getAttribute("class") . Во-первых, вам нужно использовать itemsContainer.children[i] . Во-вторых, .getAttribute("class") не работал у меня в IE, поэтому я переключил его только на.className .

Наконец, itemsContainer.children[i].nextSibling не работал у меня, но он достаточно прост, чтобы просто изменить его на itemsContainer.children , чтобы получить следующего брата.

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

Window.onload = function() { var itemsContainer = document.getElementById("cities-drop"); document.addEventListener("*****",function(event) { if (event.keyCode == 40 && itemsContainer.style.display=="block") { event.preventDefault(); var previousHoveredChoice = itemsContainer.querySelector(".hovered"); previousHoveredChoice.className = ""; var currentHoveredChoice = previousHoveredChoice.nextSibling; if (currentHoveredChoice) { currentHoveredChoice.className = "hovered"; } } }); //following code is copy-pasted from the live example //just to close the onload function handler in this solution document.addEventListener("*****",function(event){ if (event.keyCode == 27) { if (document.getElementById("cities-drop").style.display=="block"){ document.getElementById("cities-drop").style.display="none"; } } }); //end of copy-pasted code };

Есть несколько вещей, которые я вижу, что может быть проблемой. Прежде всего, вы обновляете itemsContainer.children[i].nextSibling , который равен itemsContainer.children . Поэтому всегда выбирается последний элемент, если вы пропустите перерыв. itemsComtainer всегда будет зависать, если есть элемент, соответствующий классу.

Вторая проблема - это то, что Travesty3 указывает на его ответ.

Я также изменил условие if, чтобы проверить, находится ли зависавший класс на одном из дочерних элементов, а не на самом контейнере.

If (itemsContainer.children[i].getAttribute("class").match("hovered"))

Я изменил обработчик событий со следующими строками кода, и это, кажется, отлично работает:

Document.addEventListener("*****",function(event){ if (event.keyCode === 40 && itemsContainer.style.display==="block") { event.preventDefault(); for (var i=0,l=itemsContainer.children.length;i

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

Если пользовательский опыт важен, я бы рекомендовал использовать для этого фреймворк и плагин. Я лично предпочитаю jquery и jquery ui, и есть несколько плагинов для выбора drop downs. Еще одно преимущество заключается в том, что если javascript отключен клиентом или ваш javascript будет ошибочным по какой-то причине, большинство плагинов возвращаются к обычному собственному элементу select, который все равно будет работать нормально.

Я сам использовал этот плагин для selectbox для простого выпадающего списка: http://www.abeautifulsite.net/blog/2011/01/jquery-selectbox-plugin/

Изменить: Я отменяю эту рекомендацию, так как она не работает, если несколько элементов имеют одинаковое имя. Если это важно, вы должны проверить плагин Filament Group selectmenu: http://filamentgroup.com/lab/jquery_ui_selectmenu_an_aria_accessible_plugin_for_styling_a_html_select/ //Изменить

И плагин автозаполнения jquery для combobox, также поддерживающий письменный ввод: http://jqueryui.com/demos/autocomplete/

Обработка событий

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

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

Тип события - это строка, определяющая тип действия, вызвавшего событие. Тип «mousemove», например, означает, что пользователь переместил указатель мыши. Тип «keydown» означает, что была нажата клавиша на клавиатуре. А тип «load» означает, что завершилась загрузка документа (или какого-то другого ресурса) из сети. Поскольку тип события - это просто строка, его иногда называют именем события.

Цель события - это объект, в котором возникло событие или с которым это событие связано. Когда говорят о событии, обычно упоминают тип и цель события. Например, событие «load» объекта Window или событие «click» элемента . Самыми типичными целями событий в клиентских приложениях на языке JavaScript являются объекты Window, Document и Element, но некоторые типы событий могут происходить и в других типах объектов.

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

Объект события - это объект, связанный с определенным событием и содержащий информацию об этом событии. Объекты событий передаются функции обработчика события в виде аргумента (кроме IE8 и более ранних версий, где объект события доступен только в виде глобальной переменной event). Все объекты событий имеют свойство type , определяющее тип события, и свойство target , определяющее цель события.

Для каждого типа события в связанном объекте события определяется набор свойств. Например, объект, связанный с событиями от мыши, включает координаты указателя мыши, а объект, связанный с событиями от клавиатуры, содержит информацию о нажатой клавише и о нажатых клавишах-модификаторах. Для многих типов событий определяются только стандартные свойства, такие как type и target, и не передается никакой дополнительной полезной информации. Для таких типов событий важно само наличие происшествия события, и никакая другая информация не имеет значения.

Распространение события - это процесс, в ходе которого браузер решает, в каких объектах следует вызвать обработчики событий. В случае событий, предназначенных для единственного объекта (таких как событие «load» объекта Window), надобность в их распространении отсутствует. Однако, когда некоторое событие возникает в элементе документа, оно распространяется, или «всплывает», вверх по дереву документа.

Если пользователь щелкнет мышью на гиперссылке, событие «mousemove» сначала будет возбуждено в элементе , определяющем эту ссылку. Затем оно будет доставлено вмещающим элементам: возможно, элементу

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

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

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

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

Дело осложняется тем, что каждый прием имеет две версии. Свойство обработчика события можно установить в программном коде на языке JavaScript или в элементе документа, определив соответствующий атрибут непосредственно в разметке HTML. Регистрация обработчиков вызовом метода может быть выполнена стандартным методом с именем addEventListener(), который поддерживается всеми браузерами, кроме IE версии 8 и ниже, и другим методом, с именем attachEvent(), поддерживаемым всеми версиями IE до IE9.

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

Самый простой способ зарегистрировать обработчик события заключается в том, чтобы присвоить свойству целевого объекта события желаемую функцию обработчика. По соглашению свойства обработчиков событий имеют имена, состоящие из слова «on», за которым следует имя события: onclick, onchange, onload, onmouseover и т.д. Обратите внимание, что эти имена свойств чувствительны к регистру и в них используются только строчные символы, даже когда имя типа события состоит из нескольких слов (например «readystatechange»). Ниже приводятся два примера регистрации обработчиков событий:

// Присвоить функцию свойству onload объекта Window. // Функция - обработчик события: она вызывается, когда документ будет загружен window.onload = function() { // Отыскать элемент var elt = document.getElementById("shipping_address"); // Зарегистрировать обработчик события, который будет вызываться // непосредственно перед отправкой формы elt.onsubmit = function() { return validate(this); } }

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

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

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

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

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

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

onafterprint onfocus ononline onresize onbeforeprint onhashchange onpagehide onstorage onbeforeunload onload onpageshow onundo onblur onmessage onpopstate onunload onerror onoffline onredo

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

addEventListener()

В стандартной модели событий, поддерживаемой всеми браузерами, кроме IE версии 8 и ниже, целью события может быть любой объект - включая объекты Window и Document и все объекты Elements элементов документа - определяющий метод с именем addEventListener() , с помощью которого можно регистрировать обработчики событий для этой цели.

Метод addEventListener() принимает три аргумента. Первый - тип события, для которого регистрируется обработчик. Тип (или имя) события должен быть строкой и не должен включать префикс «on», используемый при установке свойств обработчиков событий. Вторым аргументом методу addEventListener() передается функция, которая должна вызываться при возникновении события указанного типа. В последнем аргументе методу addEventListener() передается логическое значение. Обычно в этом аргументе передается значение false. Если передать в нем значение true, функция будет зарегистрирована как перехватывающий обработчик и будет вызываться в другой фазе распространения события.

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

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

Щелкните меня! var b = document.getElementById("mybutton"); b.onclick = function() { alert("Спасибо, что щелкнули на мне!"); }; b.addEventListener("click", function() {alert("Еще раз спасибо!")}, false);

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

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

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

Internet Explorer версии ниже IE9 не поддерживает методы addEventListener() и removeEventListener(). В версии IE5 и выше определены похожие методы, attachEvent() и detachEvent() . Поскольку модель событий в IE не поддерживает фазу перехвата, методы attachEvent() и detachEvent() принимают только два аргумента: тип события и функцию обработчика, при этом в первом аргументе методам в IE передается имя свойства обработчика с префиксом «on», а не тип события без этого префикса.

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

После регистрации обработчика событий веб-браузер будет вызывать его автоматически, когда в указанном объекте будет возникать событие указанного типа. В этом разделе подробно описывается порядок вызова обработчиков событий, аргументы обработчиков, контекст вызова (значение this) и назначение возвращаемого значения обработчика. К сожалению, некоторые из этих подробностей отличаются между IE версии 8 и ниже и другими браузерами.

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

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

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

Объект события передается обработчикам событий, зарегистрированным с помощью метода attachEvent(), но они также могут использовать переменную window.event.

При регистрации обработчика события посредством HTML-атрибута браузер преобразует строку с программным кодом на языке JavaScript в функцию. Браузеры, отличные от IE, создают функцию с единственным аргументом event. В IE создается функция, не принимающая аргументов. Если в таких функциях использовать идентификатор event, он будет ссылаться на window.event. В любом случае обработчики событий, определяемые в разметке HTML, могут ссылаться на объект события, используя идентификатор event.

Контекст обработчиков событий

Когда обработчик событий регистрируется установкой свойства, это выглядит как определение нового метода элемента документа:

E.onclick = function() { /* реализация обработчика */ };

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

В обработчиках ключевое слово this ссылается на целевой объект, даже когда они были зарегистрированы с помощью метода addEventListener(). Однако, к сожалению, это не относится к методу attachEvent(): обработчики, зарегистрированные с помощью метода attachEvent(), вызываются как функции, и в них ключевое слово this ссылается на глобальный (Window) объект. Эту проблему можно решить следующим способом:

/* Регистрирует указанную функцию как обработчик событий указанного типа в указанном объекте. Гарантирует, что обработчик всегда будет вызываться как метод целевого объекта. */ function addEvent(target, type, handler) { if (target.addEventListener) target.addEventListener(type, handler, false); else target.attachEvent("on" + type, function(event) { // Вызвать обработчик как метод цели, // и передать ему объект события return handler.call(target, event); }); }

Обратите внимание, что обработчики событий, зарегистрированные таким способом, нельзя удалить, потому что ссылка на функцию-обертку, передаваемую методу attachEvent(), нигде не сохраняется, чтобы ее можно было передать методу detachEvent().

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

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

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

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

Важно понимать, что учитываются значения, возвращаемые обработчиками событий, только если обработчики зарегистрированы посредством установки свойств. Обработчики, зарегистрированные с помощью addEventListener() или attachEvent() вместо этого должны вызывать метод preventDefault() или устанавливать свойство returnValue объекта события.

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

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

В следующем фрагменте демонстрируется обработчик события клика по гиперссылке, который использует все три способа отмены события (блокирует переход пользователя по ссылке):

Window.onload = function() { // Найти все ссылки var a_href = document.getElementsByTagName("a"); // Добавить обработчик события click (не для IE

Текущий проект модуля «DOM Events 3» определяет в объекте Event свойство с именем defaultPrevented . Оно пока поддерживается не всеми браузерами, но суть его в том, что при обычных условиях оно имеет значение false и принимает значение true только в случае вызова метода preventDefault().

Отмена действий, по умолчанию связанных с событием, - это лишь одна из разновидностей отмены события. Имеется также возможность остановить распространение события. В браузерах, поддерживающих метод addEventListener(), объект события имеет метод stopPropagation() , вызов которого прерывает дальнейшее распространение события. Если в том же целевом объекте будут зарегистрированы другие обработчики этого события, то остальные обработчики все равно будут вызваны, но никакие другие обработчики событий в других объекта не будут вызваны после вызова метода stopPropagation().

В IE версии 8 и ниже метод stopPropagation() не поддерживается. Вместо этого объект события в IE имеет свойство cancelBubble . Установка этого свойства в значение true предотвращает распространение события.

Текущий проект спецификации «DOM Events 3» определяет в объекте Event еще один метод - метод с именем stopImmediatePropagation() . Подобно методу stopPropagation(), он предотвращает распространение события по любым другим объектам. Но кроме того, он также предотвращает вызов любых других обработчиков событий, зарегистрированных в том же объекте.

addEventListener() works by adding a function or an object that implements EventListener to the list of event listeners for the specified event type on the EventTarget on which it"s called.

Syntax target .addEventListener(type , listener[ , options ]); target .addEventListener(type , listener[ , useCapture ]); target .addEventListener(type , listener[ , useCapture , wantsUntrusted ]); // Gecko/Mozilla only Parameters type A case-sensitive string representing the event type to listen for. listener The object which receives a notification (an object that implements the Event interface) when an event of the specified type occurs. This must be an object implementing the EventListener interface, or a JavaScript function . See for details on the callback itself. options Optional An options object that specifies characteristics about the event listener. The available options are: useCapture Optional A Boolean indicating whether events of this type will be dispatched to the registered listener before being dispatched to any EventTarget beneath it in the DOM tree. Events that are bubbling upward through the tree will not trigger a listener designated to use capture. Event bubbling and capturing are two ways of propagating events which occur in an element that is nested within another element, when both elements have registered a handle for that event. The event propagation mode determines the order in which elements receive the event. See DOM Level 3 Events and JavaScript Event order for a detailed explanation. If not specified, useCapture defaults to false .

Note: For event listeners attached to the event target, the event is in the target phase, rather than the capturing and bubbling phases. Events in the target phase will trigger all listeners on an element in the order they were registered, regardless of the useCapture parameter.

Note: useCapture has not always been optional. Ideally, you should include it for the widest possible browser compatibility.

WantsUntrusted A Firefox (Gecko)-specific parameter. If true , the listener receives synthetic events dispatched by web content (the default is false for browser chrome and true for regular web pages). This parameter is useful for code found in add-ons as well as the browser itself.

Return value Usage notes The event listener callback

The event listener can be specified as either a callback function or an object that implements EventListener , whose handleEvent() method serves as the callback function.

The callback function itself has the same parameters and return value as the handleEvent() method; that is, the callback accepts a single parameter: an object based on Event describing the event which has occurred, and it returns nothing.

For example, an event handler callback that can be used to handle both fullscreenchange and fullscreenerror might look like this:

Function eventHandler(event) { if (event.type == "fullscreenchange") { /* handle a full screen toggle */ } else /* fullscreenerror */ { /* handle a full screen toggle error */ } }

Safely detecting option support

In older versions of the DOM specification, the third parameter of addEventListener() was a Boolean value indicating whether or not to use capture. Over time, it became clear that more options were needed. Rather than adding more parameters to the function (complicating things enormously when dealing with optional values), the third parameter was changed to an object which can contain various properties defining the values of options to configure the process of removing the event listener.

Because older browsers (as well as some not-too-old browsers) still assume the third parameter is a Boolean, you need to build your code to handle this scenario intelligently. You can do this by using feature detection for each of the options you"re interested in.

For example, if you want to check for the passive option:

Let passiveSupported = false; try { const options = { get passive() { // This function will be called when the browser // attempts to access the passive property. passiveSupported = true; return false; } }; window.addEventListener("test", null, options); window.removeEventListener("test", null, options); } catch(err) { passiveSupported = false; }

This creates an options object with a getter function for the passive property; the getter sets a flag, passiveSupported , to true if it gets called. That means that if the browser checks the value of the passive property on the options object, passiveSupported will be set to true ; otherwise, it will remain false . We then call addEventListener() to set up a fake event handler, specifying those options, so that the options will be checked if the browser recognizes an object as the third parameter. Then, we call removeEventListener() to clean up after ourselves. (Note that handleEvent() is ignored on event listeners that aren"t called.)

You can check whether any option is supported this way. Just add a getter for that option using code similar to what is shown above.

Then, when you want to create an actual event listener that uses the options in question, you can do something like this:

SomeElement.addEventListener("mouseup", handleMouseUp, passiveSupported ? { passive: true } : false);

Examples Add a simple listener

This example demonstrates how to use addEventListener() to watch for mouse clicks on an element.

HTML
one
two
JavaScript // Function to change the content of t2 function modifyText() { const t2 = document.getElementById("t2"); if (t2.firstChild.nodeValue == "three") { t2.firstChild.nodeValue = "two"; } else { t2.firstChild.nodeValue = "three"; } } // Add event listener to table const el = document.getElementById("outside"); el.addEventListener("click", modifyText, false);

In this code, modifyText() is a listener for click events registered using addEventListener() . A click anywhere in the table bubbles up to the handler and runs modifyText() .

Result Event listener with anonymous function

Here, we"ll take a look at how to use an anonymous function to pass parameters into the event listener.

HTML
one
two
JavaScript // Function to change the content of t2 function modifyText(new_text) { var t2 = document.getElementById("t2"); t2.firstChild.nodeValue = new_text; } // Function to add event listener to table var el = document.getElementById("outside"); el.addEventListener("click", function(){modifyText("four")}, false);

Notice that the listener is an anonymous function that encapsulates code that is then, in turn, able to send parameters to the modifyText() function, which is responsible for actually responding to the event.

Result Event listener with an arrow function

This example demonstrates a simple event listener implemented using arrow function notation.

HTML
one
two
JavaScript // Function to change the content of t2 function modifyText(new_text) { const t2 = document.getElementById("t2"); t2.firstChild.nodeValue = new_text; } // Add event listener to table with an arrow function const el = document.getElementById("outside"); el.addEventListener("click", () => { modifyText("four"); }, false); Result

Please note that while anonymous and arrow functions are similar, they have different this bindings. While anonymous (and all traditional JavaScript functions) create their own this bindings, arrow functions inherit the this binding of the containing function.

That means that the variables and constants available to the containing function are also available to the event handler when using an arrow function.

Example of options usage HTML outer, once & none-once middle, capture & none-capture inner1, passive & preventDefault(which is not allowed) inner2, none-passive & preventDefault(not open new page) CSS .outer, .middle, .inner1, .inner2 { display:block; width:520px; padding:15px; margin:15px; text-decoration:none; } .outer { border:1px solid red; color:red; } .middle { border:1px solid green; color:green; width:460px; } .inner1, .inner2 { border:1px solid purple; color:purple; width:400px; } JavaScript const outer = document.getElementsByClassName("outer") ; const middle = document.getElementsByClassName("middle"); const inner1 = document.getElementsByClassName("inner1"); const inner2 = document.getElementsByClassName("inner2"); const capture = { capture: true }; const noneCapture = { capture: false }; const once = { once: true }; const noneOnce = { once: false }; const passive = { passive: true }; const nonePassive = { passive: false }; outer.addEventListener("click", onceHandler, once); outer.addEventListener("click", noneOnceHandler, noneOnce); middle.addEventListener("click", captureHandler, capture); middle.addEventListener("click", noneCaptureHandler, noneCapture); inner1.addEventListener("click", passiveHandler, passive); inner2.addEventListener("click", nonePassiveHandler, nonePassive); function onceHandler(event) { alert("outer, once"); } function noneOnceHandler(event) { alert("outer, none-once, default"); } function captureHandler(event) { //event.stopImmediatePropagation(); alert("middle, capture"); } function noneCaptureHandler(event) { alert("middle, none-capture, default"); } function passiveHandler(event) { // Unable to preventDefault inside passive event listener invocation. event.preventDefault(); alert("inner1, passive, open new page"); } function nonePassiveHandler(event) { event.preventDefault(); //event.stopPropagation(); alert("inner2, none-passive, default, not open new page"); } Result

Click the outer, middle, inner containers respectively to see how the options work.

Before using a particular value in the options object, it"s a good idea to ensure that the user"s browser supports it, since these are an addition that not all browsers have supported historically. See for details.

Other notes Why use addEventListener ?

addEventListener() is the way to register an event listener as specified in W3C DOM. The benefits are as follows:

  • It allows adding more than a single handler for an event. This is particularly useful for AJAX libraries, JavaScript modules, or any other kind of code that needs to work well with other libraries/extensions.
  • It gives you finer-grained control of the phase when the listener is activated (capturing vs. bubbling).
  • It works on any DOM element, not just HTML elements.
The value of this within the handler

It is often desirable to reference the element on which the event handler was fired, such as when using a generic handler for a set of similar elements.

If attaching a handler function to an element using addEventListener() , the value of this inside the handler is a reference to the element. It is the same as the value of the currentTarget property of the event argument that is passed to the handler.

My_element.addEventListener("click", function (e) { console.log(this.className) // logs the className of my_element console.log(e.currentTarget === this) // logs `true` }) my_element.addEventListener("click", (e) => { console.log(this.className) // WARNING: `this` is not `my_element` console.log(e.currentTarget === this) // logs `false` })

Specifying this using bind()

Note: useCapture is not supported, as IE 8 does not have any alternative method. The following code only adds IE 8 support. This IE 8 polyfill only works in standards mode: a doctype declaration is required.

(function() { if (!Event.prototype.preventDefault) { Event.prototype.preventDefault=function() { this.returnValue=false; }; } if (!Event.prototype.stopPropagation) { Event.prototype.stopPropagation=function() { this.cancelBubble=true; }; } if (!Element.prototype.addEventListener) { var eventListeners=; var addEventListener=function(type,listener /*, useCapture (will be ignored) */) { var self=this; var wrapper=function(e) { e.target=e.srcElement; e.currentTarget=self; if (typeof listener.handleEvent != "undefined") { listener.handleEvent(e); } else { listener.call(self,e); } }; if (type=="DOMContentLoaded") { var wrapper2=function(e) { if (document.readyState=="complete") { wrapper(e); } }; document.attachEvent("onreadystatechange",wrapper2); eventListeners.push({object:this,type:type,listener:listener,wrapper:wrapper2}); if (document.readyState=="complete") { var e=new Event(); e.srcElement=window; wrapper2(e); } } else { this.attachEvent("on"+type,wrapper); eventListeners.push({object:this,type:type,listener:listener,wrapper:wrapper}); } }; var removeEventListener=function(type,listener /*, useCapture (will be ignored) */) { var counter=0; while (counterAlternate Name Uses the non-standard name: attachEvent Opera Full support 7 Safari Full support 1 WebView Android Full support 1

Notes

Full support 1

Notes

Notes Before Chrome 49, the type and listener parameters were optional. Chrome Android Full support 18

Notes

Full support 18

Notes

Notes Before Chrome 49, the type and listener parameters were optional. Firefox Android Full support 4 Opera Android Full support 10.1 Safari iOS Full support 1 useCapture parameter made optional Chrome Full support 1 Edge Full support Yes Firefox Full support 6 IE Full support 9 Opera Full support 11.6 Safari Full support Yes WebView Android Full support 1 Chrome Android Full support 18 Firefox Android Full support 6 Opera Android Full support 12 Samsung Internet Android Full support Yes Form with options object supported (third parameter can be either options or a Boolean , for backwards compatibility) Chrome Full support 49 Edge Full support Yes Firefox Full support 49 IE No support No Opera Full support Yes Safari Full support 10 WebView Android Full support 49 Chrome Android Full support 49 Firefox Android Full support 49 Safari iOS Full support 10 options: capture option Chrome Full support 52 Edge Full support Yes Firefox Full support Yes IE No support No Opera Full support Yes Safari Full support Yes WebView Android Full support 52 Chrome Android Full support 52 Opera Android Full support Yes Safari iOS Full support Yes options: once option Chrome Full support 55 Edge Full support Yes Firefox Full support 50 IE No support No Opera Full support 42 Safari Full support Yes Firefox Android Full support 50 Opera Android Full support 42 Safari iOS Full support Yes Samsung Internet Android Full support 6.0 options: passive option Chrome Full support 51 Edge Full support Yes Firefox Full support Yes IE No support No Opera Full support Yes Safari Full support Yes WebView Android Full support 51 Chrome Android Full support 51 Firefox Android Full support Yes Opera Android Full support Yes Safari iOS Full support Yes Samsung Internet Android Full support 5.0 options: passive option defaults to true for touchstart and touchmove events Chrome Full support 55 Edge No support No Firefox Full support 61 IE No support No Opera ? Safari No support No WebView Android Full support 55 Chrome Android Full support 55 Firefox Android Full support 61 Opera Android ? Safari iOS No support No Samsung Internet Android Full support 6.0 options: passive option defaults to true for wheel and mousewheel events Chrome Full support 73 Edge No support No Firefox ? IE No support No Opera ? Safari No support No WebView Android Full support 73 Chrome Android Full support 73 Firefox Android ? Opera Android ? Safari iOS No support No Samsung Internet Android ? Legend Full support Full support No support No support Compatibility unknown Compatibility unknown See implementation notes. See implementation notes. Uses a non-standard name. Uses a non-standard name.

Приложить событие щелчка на элемента. Когда пользователь нажимает на кнопку, выход "Hello World" в

Элемент с идентификатором = «демо»:


document.getElementById("demo").innerHTML = "Hello World";
});

Попробуй сам "

Больше "Try it Yourself" примеры ниже.

Определение и использование

addEventListener() метод придает обработчик события для указанного элемента.


пример

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

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

Document.getElementById("myBtn").addEventListener("click", myFunction);

Попробуй сам "
пример

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

Этот пример показывает, как добавить много событий на одной и той же элемента:

Document.getElementById("myBtn").addEventListener("mouseover", myFunction);
document.getElementById("myBtn").addEventListener("click", someOtherFunction);
document.getElementById("myBtn").addEventListener("mouseout", someOtherFunction);

Попробуй сам "
пример

При передаче значений параметров используйте "anonymous function" , которая вызывает указанную функцию с параметрами:

Document.getElementById("myBtn").addEventListener("click", function() {
myFunction(p1, p2);
});

Попробуй сам "
пример

Изменение цвета фона элемента:

Document.getElementById("myBtn").addEventListener("click", function(){
this.style.backgroundColor = "red";

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

Как подписаться на событие?
  • Подписаться через код HTML (не рекомендуется использовать).
  • Через код JavaScript с помощью задания элементу свойства on[событие] , где [событие] - это имя определённого события.
  • Через код JavaScript с помощью специального метода addEventListener .
Подписка на событие через код HTML

Данный способ основывается на использовании атрибута, который имеет вид on[событие] , где [событие] - это имя определённого события.

Основные действия: добавить к элементу определённый атрибут (например: onclick - где: on означает событие, а click - вид события) со значением, содержащим оператор или функцию. Данный оператор или функция будет выполняться при наступлении этого события у элемента.

Например, добавить к кнопке событие click , при наступлении которого будет выводиться сообщение с помощью метода alert:

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

Например, выполним вышеприведённый пример с использованием функции:

//функция, которая будет вызываться при наступлении события click у указанного элемента function myFunction() { alert("Событие click"); }

Например, добавить к кнопке событие click , при наступлении которого выполняется указанная функция:

//функция, которая будет вызываться при наступлении события click у указанного элемента function countElements() { var count = document.getElementsByTagName("*").length; alert("Количество элементов на странице:" + count.toString()); }

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

Этот способ подписки на событие осуществляется через код JavaScript с помощью задания элементу свойства on[событие] . Основной принцип данного метода заключается в следующем:

  • Найти элемент (объект) в DOM-дереве, на событие которого Вы хотите подписаться.
  • Добавить найденному объекту свойство, которое должно иметь следующий вид:
    on[событие] , где [событие] - это имя определённого события.
    После этого необходимо данному свойству присвоить обработчик, т.е. безымянную или некоторую указанную функцию, которая будет выполняться при наступлении этого события.
  • //в качестве обработчика события будем использовать безымянную функцию: document.getElementById("myID").onclick = function { alert("Событие click"); }

    Например, добавить к кнопке, имеющей id="myButton" событие click , при наступлении которого выполняется указанная функция:

    //Найти элемент на событие, которого Вы хотите подписаться var myButton = document.getElementById("myButton"); //добавить к объекту свойство, имеющее имя on[событие] //при наступлении события click выполняется функция myFunction myButton.onclick = myFunction; //функция myFunction function myFunction() { //код функции //... }

    Если событие задаётся через атрибут, то браузер, читая код HTML, создаёт соответствующее свойство автоматически. Т.е. браузер работает с событиями только с помощью соответствующих свойств объекта (элемента).

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

    Подписка на событие через код JavaScript с помощью метода addEventListener

    Этот способ подписки на событие осуществляется через код JavaScript с помощью специального метода addEventListener . Данный способ подписки является наиболее предпочтительным и рекомендуется стандартом.

    Метод addEventListener , предназначен для добавления прослушивателя (listener) определённого события (event) к элементу и выполнения обработчика (callback) при его наступлении. Кроме метода addEventListener есть ещё один метод removeEventListener , который предназначен для выполнения обратного действия, т.е. для удаления прослушивателя.

    Синтаксис методов addEventListener и removeEventListener:

    Element.addEventListener(event, callback, phase); element.removeEventListener(event, callback, phase);

    Метод addEventListener имеет 3 параметра:

    • event (обязательный) - имя события, на которое Вы хотите подписаться (прослушивать);
    • callback (обязательный) - функция (анонимная или именованная), которая будет выполнять обработку события;
    • phase (не обязательный) - этап, на котором будет перехватываться событие. Данный параметр принимает 2 значения: true (на этапе погружения (перехвата) события) и false (на этапе всплытия события). Если данный параметр не указать, то будет использоваться значение false .

    Например, использование анонимной функции для обработки события " click ":

    Element.addEventListener("click", function { //... });

    Например, использование функции myFunction() для обработки события " click ":

    Element.addEventListener("click", myFunction); //функция myFunction function myFunction() { //... }

    Обработчик события, который Вы добавили с помощью метода addEventListener() можно при необходимости удалить с помощью метода removeEventListener() . Удалить обработчик события можно только в том случае, если он в методе addEventListener() задан в виде именованной функции. Если Вы задали обработчик в виде анонимной функции в методе addEventListener() , то его удалить с помощью метода removeEventListener() не получится.

    Например, добавить, а затем удалить обработчик myFunction для события mousemove объекта document:

    //добавить для события mousemove объекта document обработчик, заданный в виде функции myFunction document.addEventListener("mousemove",myFunction); //удалить у события mousemove объекта document обработчик, заданный в виде функции myFunction document.removeEventListener("mousemove", myFunction);

    Document.addEventListener("click",myFunction); function myFunction() { alert("I LOVE JAVASCRIPT!"); }

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

    Document.addEventListener("click",myFunction1); document.addEventListener("click",myFunction2);

    Например, добавить объекту document обработчики для следующих событий: click , mouseover , mouseout .

    Document.addEventListener("mouseover",myFunction1); document.addEventListener("click",myFunction2); document.addEventListener("mouseout",myFunction3);

    Например, для передачи обработчику значений параметров, будем использовать анонимную функцию. В этой анонимной функции будем использовать ещё одну функцию (именованную) с помощью которой и будем передавать необходимые параметры:

    Document.addEventListener("click",function() { myFunction(parameter1, parameter2); });

    Например, при наступлении события click в документе, изменить цвет фона элемента body . Обработчик события выполнить в виде анонимной функции.

    Document.addEventListner("click",function() { document.body.style.backgroundColor = green; });

    Как правильно работать с событиями

    Работать в JavaScript с документом HTML (DOM-деревом) и обрабатывать события необходимо только после того страница полностью загрузится:

    //когда вся страница загрузилась, вызываем нашу функцию pageInit window.addEventListener("load", pageInit); //функция pageInit() function pageInit() { //подписываемся на события }

    Window.addEventListener("load", function() { //подписываемся на события }

    Более правильно работать не с событием load (происходит после полной загрузки страницы), а с событием DOMContentLoaded , которое происходит после того как браузер загрузил документ HTML и построил DOM-дерево. Т.е. для того чтобы работать с DOM-деревом нет необходимости ждать пока загрузятся все ресурсы HTML-страницы достаточно чтобы браузер построил дерево DOM.

    //HTML документ загрузился и дерево DOM построено document.addEventListener("DOMContentLoaded", pageInit); //функция pageInit() function pageInit() { //подписываемся на события }

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

    Document.addEventListener("DOMContentLoaded", function() { //подписываемся на события }

    Одновременно подписать на событие сразу несколько объектов

    Например, подписать на событие click сразу все элементы p. Обработку события выполнять с помощью функции myFunction():

    Document.addEventListener("DOMContentLoaded", function() { var elementsP = document.getElementsByTagName("P"); for (var i=0; i < elementsP.length, i++) { elementsP[i].addEventListener("click", myFunction); } } //функция myFunction() function myFunction() { //... }

    Похожие статьи