Работает addeventlistener. JavaScript - Способы подписки на события
Приложить событие щелчка на элемента. Когда пользователь нажимает на кнопку, выход "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";
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 callbackThe 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 supportIn 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 listenerThis example demonstrates how to use addEventListener() to watch for mouse clicks on an element.
HTMLone |
two |
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 functionHere, we"ll take a look at how to use an anonymous function to pass parameters into the event listener.
HTMLone |
two |
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 functionThis example demonstrates a simple event listener implemented using arrow function notation.
HTMLone |
two |
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"); } ResultClick 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.
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
Notes
Full support 1Notes
Notes Before Chrome 49, the type and listener parameters were optional.Notes
Full support 18Notes
Notes Before Chrome 49, the type and listener parameters were optional.В этой статье мы рассмотрим различные способы, с помощью которых Вы можете подписаться на события элементов веб-страницы. Один из способов основан на использовании атрибутов HTML, два других способа осуществляются через код JavaScript посредством свойства on или метода addEventListener() .
Как подписаться на событие?- Подписаться через код HTML (не рекомендуется использовать).
- Через код JavaScript с помощью задания элементу свойства on[событие] , где [событие] - это имя определённого события.
- Через код JavaScript с помощью специального метода addEventListener .
Данный способ основывается на использовании атрибута, который имеет вид 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[событие] . Основной принцип данного метода заключается в следующем:
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() { //... }
У вас есть следующий прослушиватель для клавиатуры 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/
Для , чтобы добавить событие щелчка. Когда пользователь нажимает на кнопку ID = "демо" элемента выходной элемент "Hello World":
. Document.getElementById ("демо") innerHTML = "Hello World";
});
Попробуйте » Определение и использование
Метод addEventListener () используется для добавления обработчика событий для заданного элемента.
примеров
Вы можете добавить столько событий, в документе, добавляя событие не приведет к перезаписи существующего события.
Этот пример демонстрирует, как добавить два события щелчка в элементе :
Document.getElementById ("myBtn") addEventListener ("щелчок", MYFUNCTION);
Попробуйте »
примеров
Вы можете добавить различные типы событий в одном элементе.
Этот пример показывает, как добавить несколько событий с элементом :
Document.getElementById ("myBtn") addEventListener ("MouseOver", MYFUNCTION);
. Document.getElementById ("myBtn") addEventListener ("щелчок", someOtherFunction);
. Document.getElementById ("myBtn") addEventListener ("MouseOut", someOtherFunction);
Попробуйте »
примеров
При передаче значения параметра, используйте вызов функции с параметрами "анонимной функции":
document.getElementById ("myBtn"). addEventListener ("щелчок", функция () {
туРипсЫоп (p1, p2);
});
Попробуйте »
примеров
Изменить элементы Справочная информация:
document.getElementById ("myBtn"). addEventListener ("щелчок", функция () {
this.style.backgroundColor = "красный";
});
Попробуйте »
примеров
Используйте дополнительные параметры для демонстрации различных useCapture бурлит и захвата фаз:
Document.getElementById ("myDiv") addEventListener ("щелчок", туРипсЫоп, правда);