Работает addeventlistener. JavaScript - Способы подписки на события

У вас есть следующий прослушиватель для клавиатуры 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 EventTarget Определение и применение

JavaScript метод addEventListener() объекта EventTarget позволяет зарегистрировать обработчик событий определенного типа для конкретной цели.

В качестве цели могут выступать как такие объекты как Element , Document , Window , или любые другие объекты, которые поддерживают события, например, такой объект как XMLHttpRequest , который широко используется в асинхронных запросах AJAX (от англ. Asynchronous Javascript and XML - "асинхронный JavaScript и XML"), что позволяет конкретной странице обновлять только её часть, не нарушая при этом работу пользователя.

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

Поддержка браузерами JavaScript синтаксис: target .addEventListener(type , listener ); target .addEventListener(type , listener , options ); target .addEventListener(type , listener , useCapture ); type - String listener - Function options - Object useCapture - Boolean Cпецификация Document Object Model (DOM) Level 2 Events Значения параметров Параметр Описание
type Строковое значение, представляющее тип события для прослушивания (значение чувствительно к регистру). Обязательный параметр.
listener Объект, который получает уведомление при возникновении события указанного типа (объект, реализующий интерфейс Event ). Это должен быть объект, реализующий интерфейс EventListener , или функция JavaScript . Обязательный параметр.
options Объект, указывающий характеристики прослушивателя событий (является необязательным параметром ).
Доступные опции:
  • capture - Логическое значение, которое определяет будут ли события этого типа отправлены зарегистрированному прослушивателю (обработчику события) перед отправкой любому EventTarget DOM . Если передать логическое значение true , то функция будет зарегистрирована как перехватывающий обработчик и будет вызываться в фазе перехвата (capture phase bubbling phase ).
  • once - Логическое значение, которое указывает на то, что обработчик события должен быть вызван не более одного раза после добавления. Если указано логическое значение true , то прослушиватель будет автоматически удален при вызове.
  • passive - Логическое значение, которое, если соответствует значению true , указывает на то, что функция, указанная прослушивателем, никогда не отменит действие события по умолчанию (вызовет метод preventDefault() preventDefault() , то браузер пользователя проигнорирует его, и создаст при этом предупреждение в консоли.
useCapture Логическое значение, которое определяет будут ли события этого типа отправлены зарегистрированному прослушивателю (обработчику события) перед отправкой любому EventTarget , расположенному под ним в дереве DOM .
Если передать логическое значение true , то функция будет зарегистрирована как перехватывающий обработчик и будет вызываться в фазе перехвата (capture phase ). Значение по умолчанию false - обработчик события будет срабатывать в фазе всплытия (bubbling phase ). Необязательный параметр. Параметр useCapture не всегда был необязательным, в идеале, вы должны включить его для более широкой браузерной поддержки.
Пример использования Базовое использование метода Использование JavaScript метода addEventListener()
  • 1
const ul = document .querySelector("ul "), // выбираем первый элемент ul в документе listElements = document .querySelectorAll("li "); // выбираем все элементы li в документе const myFunc = function (event ) { if (event .target.tagName === "LI ") { // если объект, который отправил событие имеет значение свойства tagName равное LI event .target.style.color = "green "; // то задаем цвет текста зеленый } } ; ul .addEventListener("click ", myFunc ); // устанавливаем элементу ul обработчик события click listElements .forEach(function (elem ) { // проходим все элементы коллекции elem .addEventListener("dblclick ", function (){ // устанавливаем каждому элементу li обработчик события dblclick this .style.color = "#000 "; // задаем цвет текста черный } ) } )

В этом примере мы разместили маркированный список (

    ), внутри которого мы разместили пять элементов списка (
  • ). С помощью метода querySelector() мы выбрали первый элемент
      в документе, а с помощью метода querySelectorAll() все элементы
    • в документе, и инициализировали переменные этими значениями.

      С помощью метода addEventListener() мы установили для элемента

        обработчик события "click " (нажатие левой кнопкой мыши на элементе), который с помощью свойства target объекта Event проверяет имя тега элемента, и если это значение соответствует значению "LI ", то изменяет стиль цвета текста на зеленый при срабатывании. Обратите внимание, что зачастую удобнее установить один обработчик на родительский элемент, а не для каждого элемента по отдельности, особенно это актуально при динамическом изменении количества элементов, в этом случае отсутствует необходимость обновлять обработчики для элементов.

        Если указано логическое значение true , то функция, указанная прослушивателем, никогда не отменит действие события по умолчанию (вызовет метод preventDefault()). Если обработчик события всё же вызовет метод preventDefault() , то браузер пользователя проигнорирует его, и создаст при этом предупреждение в консоли. Логическое значение false свидетельствует о том, что функция обработчик может отменить действие события по умолчанию (может вызвать метод preventDefault()).

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

        Чтобы предотвратить эту проблему, некоторые браузеры (в частности, и ) изменили значение по умолчанию параметра passive на true для событий touchstart и touchmove в узлах уровня документа Window , Document и Document .body. Это предотвращает вызов прослушивателя событий, поэтому он не может блокировать отрисовку страницы во время прокрутки.

        Вам не нужно беспокоиться о значении passive для базового события прокрутки (scroll ), так как его нельзя отменить, прослушиватели событий в любом случае не смогут блокировать показ страницы.

        Нюансы использования this в обработчике события

        Как правило необходимо передавать элемент, на котором сработал обработчик события, особенно это актуально при использовании обобщённого обработчика событий для элементов одного типа. Если добавить обычную функцию обработчик события к элементу с помощью метода addEventListener() , то значением this внутри такого обработчика будет являться ссылка на элемент. Значение this будет совпадать со значением свойства currentTarget аргумента события объекта Event , передаваемого обработчику события, например:

        elem .addEventListener("click ", function (e ) { console .log(this .className); // выведет в консоль значение свойства className элемента elem console .log(e .currentTarget === this ); // true } )

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

        elem .addEventListener("click ", (e ) => { console .log(this .className); // this не будет ссылаться на элемент elem console .log(e .currentTarget === this ); // false }

        Давайте разберем еще ситуацию, при которой обработчик события указан как атрибут события на HTML элементе. Код JavaScript в значении атрибута эффективно упаковывается в функцию обработчика, которая связывает значение this способом, соответствующим методу addEventListener() (this в коде представляет ссылку на элемент):

        // выведет в консоль значение свойства id элемента

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

        // this не будет ссылаться на элемент, который инициировал событие } ;

        Обратите внимание на важный момент, значение this внутри функции myFunc() будет являться ссылкой на глобальный объект Window , или будет соответствовать значению undefined в том случае, если указан строгий режим (strict mode ).

        Для того, чтобы передать необходимый контекст, Вы можете использовать метод call() объекта Function , который позволяет вызывать (выполнять) функцию как метод объекта, устанавливая ее контекст исполнения (this ) в указанное значение, передавая при этом необходимые аргументы:

        const myFunc = function () { console .log(this .id) // this будет ссылаться на элемент, который инициировал событие } ;

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

        Приложить событие щелчка на элемента. Когда пользователь нажимает на кнопку, выход "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";

        Для , чтобы добавить событие щелчка. Когда пользователь нажимает на кнопку 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 ("щелчок", туРипсЫоп, правда);

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