Добавить прослушиватель событий на элементы, созданные динамически
Можно ли добавить прослушиватель событий (javascript) ко всем динамически генерируемым элементам? Я не владелец страницы, поэтому я не могу добавить слушателя статическим способом.
для всех элементов, созданных при загрузке страницы, я использую:
doc.body.addEventListener('click', function(e){
//my code
},true);
Мне нужен метод для вызова этого кода, когда на странице появляются новые элементы, но я не могу использовать jQuery (делегат, включение и т. Д. Не могут работать в моем проекте). Как я могу это сделать?
8 ответов
Похоже, вам нужно следовать стратегии делегирования, не возвращаясь к библиотеке. Я разместил пример кода в скрипке здесь: 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
}
});
ПРЕДОСТЕРЕЖЕНИЯ! Пример Fiddle включает только код для совместимых со стандартами браузеров (то есть IE9+ и почти всех версий всех остальных). Если вам нужно поддерживать "старые IE" attachEvent
тогда вы также захотите предоставить свою собственную оболочку для соответствующих собственных функций. (Есть много хороших дискуссий по этому поводу; мне нравится решение, которое Николас Закас предлагает в своей книге " Профессиональный JavaScript для веб-разработчиков".)
Зависит от того, как вы добавляете новые элементы.
Если вы добавите с помощью createElement
, вы можете попробовать это:
var btn = document.createElement("button");
btn.addEventListener('click', masterEventHandler, false);
document.body.appendChild(btn);
Тогда вы можете использовать masterEventHandler()
обрабатывать все клики.
Неясной проблемой, которую стоит здесь отметить, может быть и этот факт, который я только что обнаружил:
Если у элемента есть
z-index
установлен в-1
или меньше, вы можете подумать, что слушатель не привязан, хотя на самом деле это так, но браузер думает, что вы нажимаете на более высокийz-index
элемент.
Проблема в этом случае не в том, что слушатель не привязан, а в том, что он не может получить фокус, потому что что-то еще (например, возможно, скрытый элемент) находится поверх вашего элемента, и что то, что вместо этого получить фокус (что означает: событие не запускается). К счастью, вы можете легко обнаружить это, щелкнув элемент правой кнопкой мыши, выбрав "проверить" и проверив, является ли то, что вы нажали, "проверяется".
Я использую Chrome и не знаю, затронуты ли другие браузеры. Но его было трудно найти, потому что функционально он во многом напоминает проблему с несвязанным слушателем. Я исправил это, удалив из CSS строку: z-index:-1
;
Когда вам нужно поддерживать только «современные» веб-браузеры (не Microsoft Internet Explorer), наблюдатели мутаций — правильный инструмент для этой задачи:
new MutationObserver(function(mutationsList, observer) {
for(const mutation of mutationsList) {
if (mutation.type === 'childList') {
// put your own source code here
}
}
}).observe(document.body, {childList: true, subtree: true});
Я создал небольшую функцию для добавления динамических слушателей событий, аналогичных jQuery.on()
,
Он использует ту же идею, что и принятый ответ, только то, что использует Element.matches()
метод, чтобы проверить, соответствует ли цель заданной строке селектора.
addDynamicEventListener(document.body, 'click', '.myClass, li', function (e) {
console.log('Clicked', e.target.innerText);
});
Вы можете получить, если из GitHub.
Делегирование анонимной задачи динамически создаваемой 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
- MDN: https://developer.mozilla.org/en-US/docs/Web/API/Event/Comparison_of_Event_Targets
- Точки вставки:
Возможно, вы захотите взглянуть на эту библиотеку: https://github.com/Financial-Times/ftdomdelegate, сжатый с помощью сжатия 1,8 КБ
Он предназначен для привязки к событиям на всех целевых элементах, соответствующих данному селектору, независимо от того, существует ли что-либо в DOM во время регистрации или нет.
Вам нужно импортировать скрипт, а затем создать его следующим образом:
var delegate = new Delegate(document.body);
delegate.on('click', 'button', handleButtonClicks);
// Listen to all touch move
// events that reach the body
delegate.on('touchmove', handleTouchMove);
});
Использование classList
свойство связывать более одного класса одновременно
var container = document.getElementById("table");
container.classList.add("row", "oddrow", "firstrow");