Добавить прослушиватель событий к элементам, созданным динамически
Можно ли добавить прослушиватель событий (Javascript) для всех динамически генерируемых элементов?
Я не владелец страницы, поэтому не могу добавить слушателя статическим способом.
Для всех элементов, созданных при загрузке страницы, я использую:
doc.body.addEventListener('click', function(e){
//my code
},true);
Мне нужен метод для вызова этого кода, когда на странице появляются новые элементы, но я не могу использовать jQuery (делегирование, включение и т.д. не может работать в моем проекте). Как я могу это сделать?
Ответы
Ответ 1
Похоже, вам нужно продолжать стратегию делегации, не возвращаясь в библиотеку. Я разместил код примера в Fiddle здесь: http://jsfiddle.net/founddrama/ggMUn/
Суть его состоит в том, чтобы использовать target
в объекте event
для поиска интересующих вас элементов и отвечать соответствующим образом. Что-то вроде:
document.querySelector('body').addEventListener('click', function(event) {
if (event.target.tagName.toLowerCase() === 'li') {
// do your action on your 'li' or whatever it is you're listening for
}
});
CAVEATS! В примере Fiddle используется только код для совместимых со стандартами браузеров (например, IE9 + и почти каждая версия всех остальных). Если вам нужно поддерживать "старый IE" attachEvent
, то вы также захотите предоставить свою собственную обертку вокруг собственных собственных функций. (Здесь много хороших дискуссий, мне нравится решение, которое Николай Закас предлагает в своей книге "Профессиональный JavaScript для веб-разработчиков".)
Ответ 2
Зависит от того, как вы добавляете новые элементы.
Если вы добавите с помощью createElement
, вы можете попробовать следующее:
var btn = document.createElement("button");
btn.addEventListener('click', masterEventHandler, false);
document.body.appendChild(btn);
Затем вы можете использовать masterEventHandler()
для обработки всех кликов.
Ответ 3
Я создал небольшую функцию для добавления динамических прослушивателей событий, похожих на jQuery.on()
.
Он использует ту же идею, что и принятый ответ, только то, что он использует метод Element.matches()
, чтобы проверить, соответствует ли цель данной строке селектора.
addDynamicEventListener(document.body, 'click', '.myClass, li', function (e) {
console.log('Clicked', e.target.innerText);
});
Вы можете получить, если из github.
Ответ 4
Делегирование анонимной задачи динамически создаваемому HTML
elements
с помощью event.target.classList.contains('someClass')
- возвращает
true
или false
- например.
let myEvnt = document.createElement('span');
myEvnt.setAttribute('class', 'someClass');
myEvnt.addEventListener('click', e => {
if(event.target.classList.contains('someClass')){
console.log(${event.currentTarget.classList})
}})
- Ссылка: https://gomakethings.com/attaching-multiple-elements-to-a-single-event-listener-in-vanilla-js/
-
Хорошо прочитано: https://eloquentjavascript.net/15_event.html#h_NEhx0cDpml
- MDN: https://developer.mozilla.org/en-US/docs/Web/API/Event/Comparison_of_Event_Targets
- Точки вставки:
Ответ 5
Неясная проблема, на которую стоит обратить внимание, также может быть фактом, который я только что обнаружил:
Если для элемента z-index
установлено значение -1
или меньше, вы можете подумать, что слушатель не связан, хотя на самом деле это так, но браузер считает, что вы нажимаете на элемент с более высоким z-index
.
Проблема, в данном случае, не в том, что слушатель не связан, а вместо этого не может получить фокус, потому что что-то еще (например, возможно, скрытый элемент) находится поверх вашего элемента, и что вместо этого получите фокус (имеется в виду: событие не запускается). К счастью, вы можете обнаружить это достаточно легко, щелкнув правой кнопкой мыши по элементу, выбрав "проверить" и проверив, является ли то, на что вы нажали, "проверяемым".
Я использую Chrome, и я не знаю, затронуты ли другие браузеры. Но это было трудно найти, потому что функционально это во многом напоминает проблему, когда слушателя не связывают. Я исправил это, удалив из CSS строку: z-index:-1
;
Ответ 6
Использовать свойство classList
для привязки более одного класса за раз
var container = document.getElementById("table");
container.classList.add("row", "oddrow", "firstrow");