Добавить прослушиватель событий на элементы, созданные динамически

Можно ли добавить прослушиватель событий (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.

Делегирование анонимной задачи динамически создаваемой HTMLelements с event.target.classList.contains('someClass')

  1. возвращается true или же false
  2. например. let myEvnt = document.createElement('span');myEvnt.setAttribute('class', 'someClass');myEvnt.addEventListener('click', e => {if(event.target.classList.contains('someClass')){console.log(${event.currentTarget.classList})}})

  3. Ссылка: https://gomakethings.com/attaching-multiple-elements-to-a-single-event-listener-in-vanilla-js/

  4. Хорошего чтения: https://eloquentjavascript.net/15_event.html
  5. MDN: https://developer.mozilla.org/en-US/docs/Web/API/Event/Comparison_of_Event_Targets
  6. Точки вставки:

Возможно, вы захотите взглянуть на эту библиотеку: 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");
Другие вопросы по тегам