Работает 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 | Объект, указывающий характеристики прослушивателя событий (является необязательным параметром
). Доступные опции:
|
useCapture | Логическое значение, которое определяет будут ли события этого типа отправлены зарегистрированному прослушивателю (обработчику события) перед отправкой любому EventTarget
, расположенному под ним в дереве DOM
. Если передать логическое значение true , то функция будет зарегистрирована как перехватывающий обработчик и будет вызываться в фазе перехвата (capture phase ). Значение по умолчанию false - обработчик события будет срабатывать в фазе всплытия (bubbling phase ). Необязательный параметр. Параметр useCapture не всегда был необязательным, в идеале, вы должны включить его для более широкой браузерной поддержки. |
- 1
В этом примере мы разместили маркированный список (
- ), внутри которого мы разместили пять
элементов списка (
- ). С помощью метода 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 ("щелчок", туРипсЫоп, правда);
- в документе, и инициализировали переменные этими значениями.
Похожие статьи
-
Простая цифровая антенна своими руками: требования к устройству
Иногда телевизионная антенна выходит из строя в самый неподходящий момент, или ее просто не оказывается под рукой. Например, во время поездки на дачу. В таком случае возникает вопрос, как сделать антенну для телевизора своими руками из...
-
Как правильно ухаживать за рулонным газоном Уход за рулонным газоном зимой
Рулонный газон, вопреки расхожему мнению о трудностях эксплуатации, напротив, требует минимального ухода. Уход сразу после укладки Сразу после укладки по газону не рекомендуется ходить, бегать, играть в активные игры. Через несколько дней,...
-
Нож "Скиннер": характеристики и отзывы
Одним из непременных атрибутов каждого охотника является нож. У многих он является предметом внимания и даже гордости, к его выбору подходят со всей тщательностью. Для правильного подбора охотничьего ножа нужно определиться со способами...
-
Охота на тетерева весной
Является одной из самых популярных, поскольку позволяет получить охотнику не только солидный трофей, но и массу незабываемых эмоций. Своеобразна, поэтому для подготовки к данной охоте нужно знать несколько важных особенностей, чтобы не...
-
Установка циркуляционного насоса – понятная для всех технология
1. НАЗНАЧЕНИЕ ИЗДЕЛИЯ 1.1 Насосы и агрегаты центробежные одноступенчатые типа К предназначены для подачи воды, а также чистых неагрессивных жидкостей сходных с водой по вязкости с водородным показателем (рН) от 6 до 8,5, температурой до...
-
Пошаговая инструкция включения кондиционера на тепло Мобильные и настенные сплит-системы MDV
Появившаяся на рынке сравнительно недавно, но уже успевшая завоевать хорошую популярность торговая марка MDV (МДВ) предлагает широкий спектр климатического оборудования. Для большого сегмента пользователей наиболее интересны кассетные и...