JS30. Задание 25 Self-unbinding Event Listeners


В основном теоретический пост о слушателях событий, о погружении и всплытии событий, о методе "stopPropagation" и о новом методе, позволяющем запустить какое-то событие только один раз.

Разметка это три вложенных div-а.

  <div class="one">
    <div class="two">
      <div class="three">
      </div>
    </div>
  </div>

В Javascript мы выбираем все div

var divs = document.querySelectorAll("div");
и добавляем им слушатель событий "click", который вызывает функцию "logText".

 function logText(e) {
    console.log(this.classList.value);
}

divs.forEach(div => div.addEventListener("click", logText));

Когда щелкают div, в консоль выводится значение: this.classList.value. Оно показывает нам, что вызывает событие. 


Клик по самому внутреннему диву вызывает событие на всех, в которые он вложен. Происходит всплытие события.

Вначале событие произошло на диве три, потом оно распространилось на див два, потом на див один.

Такой порядок выполнения событий называется events bubbling, когда событие поднимается вверх по DOM-дереву, как пузырёк. Этому порядку соответствует установленной по умолчанию свойство capture: false

divs.forEach(div => div.addEventListener("click", logText, {
    capture: false

}));

Существует и противоположный порядок - event capturing - обработка событий спускается по DOM-дереву, захватывая элементы. Мы вполне можем изменить порядок обработки событий, указав capture: true

divs.forEach(div => div.addEventListener("click", logText, {
    capture: true
}));


Порядок выполнения событий изменился


Ну, ок. А если нам не нужно, чтобы событие выполнялось на родительских элементах?
Для этого предназначен метод stopPropagation 

 Изменим код:

function logText(e) {   
    console.log(this.classList.value);
    e.stopPropagation();

}

Теперь событие регистрируем только на том элементе, по которому кликнули.

И очень приятное нововведение - возможность запустить функцию только один раз. Это вообще замечательно.

Сравним функции

divs.forEach(div => div.addEventListener("click", logText));

и

divs.forEach(div => div.addEventListener("click", logText, {
      once: true
}));


Первый код будет запускать функцию при каждом клике, второй запустит её только один раз.
Это совсем новый способ и очень удобный. Спасибо автору за знакомство с ним.

Вот такое небольшое и несложное задание.