Добавить прослушиватель событий ко всем существующим и будущим существующим элементам DOM vanilla Javascript [дубликат]

16
задан Polarize 17 June 2015 в 01:09
поделиться

2 ответа

Обработчики привязки в native API выполняются с использованием addEventListener().

Чтобы эмулировать делегирование события jQuery, вы могли бы довольно легко создать систему, которая использует метод .matches() для проверки выбранного вами селектора.

function delegate(el, evt, sel, handler) {
    el.addEventListener(evt, function(event) {
        var t = event.target;
        while (t && t !== this) {
            if (t.matches(sel)) {
                handler.call(t, event);
            }
            t = t.parentNode;
        }
    });
}

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

Он начинается с e.target и пересекает родителей, пока не попадет в связанный элемент. Каждый раз он проверяет, соответствует ли текущий элемент селектору, и если это так, он вызывает обработчик.

Итак, вы бы назвали его следующим:

delegate(document, "click", ".some_elem", function(event) {
    this.style.border = "2px dashed orange";
});

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

function delegate(el, evt, sel, handler) {
    el.addEventListener(evt, function(event) {
        var t = event.target;
        while (t && t !== this) {
            if (t.matches(sel)) {
                handler.call(t, event);
            }
            t = t.parentNode;
        }
    });
}

delegate(document, "click", ".some_elem", function(event) {
    this.parentNode.appendChild(this.cloneNode(true));
    this.style.border = "2px dashed orange";
});
<div>
  <p class="some_elem">
    <span>
      CLICK ME
    </span>
  </p>
</div>


Вот прокладка, чтобы добавить немного больше поддержки для .matches().

HTMLElement.prototype.matches =
  HTMLElement.prototype.matches ||
  HTMLElement.prototype.matchesSelector ||
  HTMLElement.prototype.webkitMatchesSelector ||
  HTMLElement.prototype.mozMatchesSelector ||
  HTMLElement.prototype.msMatchesSelector ||
  HTMLElement.prototype.oMatchesSelector;
28
ответ дан 4 revsuser1106925 17 August 2018 в 15:17
поделиться
  • 1
    Если бы только matches() получила широкую поддержку, это было бы здорово. Сегодня он вряд ли работает в любом браузере без префикса, я думаю, что он поддерживается только в Chrome 34 и последнем Firefox. – adeneo 17 June 2015 в 01:23
  • 2
    @adeneo: Правда, хотя вы получаете довольно широкую поддержку, IE9 +, с простой прокладкой. Я добавлю. Спасибо за напоминание. – user 17 June 2015 в 01:24
  • 3
    Да, есть простой полиполк с использованием querySelectorAll – adeneo 17 June 2015 в 01:25
  • 4
    Да, это тоже заберет IE8. – user 17 June 2015 в 01:28
  • 5
    Это именно то, что я искал. Спасибо. :-) – Polarize 17 June 2015 в 01:45

Вот javascript эквивалент - on()

jQuery

$(document).on('click', '#my-id', callback);

function callback(){
   ...handler code here
}

Javascript

document.addEventListener('click', function(event) {
    if (event.target.id == 'my-id') {
      callback();
    }
});
function callback(){
   ...handler code here
}

С помощью этого подход состоит в том, чтобы использовать event.target . Конечно, по мере того, как селектор меняется, вашему коду придется больше участвовать

10
ответ дан AmmarCSE 17 August 2018 в 15:17
поделиться
  • 1
    Синтаксис DOM0 не позволяет добавлять несколько обработчиков кликов в нескольких местах. – Adam 17 June 2015 в 01:21
  • 2
    @Adam, вы говорите о различии между onclick и addEventListener? – AmmarCSE 17 June 2015 в 01:22
  • 3
    Да, вы не должны использовать старые события onclick, вы должны использовать прослушиватели событий wow -_- – EasyBB 17 June 2015 в 01:30
  • 4
    Спасибо, LOL, это более стандартизированное спасибо onclick lol – EasyBB 17 June 2015 в 01:48
  • 5
    @Adam, я вижу, что вы имеете в виду jsfiddle.net/54jgo5jg спасибо за подсказку :) – AmmarCSE 17 June 2015 в 01:49
Другие вопросы по тегам:

Похожие вопросы: