JavaScript

Event Bubbling и Event Capturing в Javascript

Spread the love

Оригинальная статья: Afraz MominEvent Bubbling and Event Capturing in Javascript

Интерактивность HTML-страницы создается благодаря Javascript. Эта интерактивность — не что иное, как куча событий, которые отслеживаются на HTML элементах. Событие может инициироваться браузером, или пользователем. Произошедшие события говорят нам, что были некоторые изменения и мы можем понять где они произошли. Это может быть событие onClick, которое указывает на то, что что-то было нажато. Другим примером может быть событие onSubmit, которое сообщает, что была отправлена некая форма.

Насколько хорошо обрабатываются эти события, определяет, насколько удобна веб-страница.

Event Bubbling и Event Capturing — это две фазы распространения событий в Javascript. Поток событий — это в основном порядок, в котором события обрабатываются на веб-странице. В Javascript поток событий происходит в три этапа:

  1. Capture Phase (Фаза распространения сверху вниз)
  2. Target Phase (Фаза цели)
  3. Bubble Phase (Фаза распространения снизу вверх)

Это распространение является двунаправленным, от window до target и обратно. Эти фазы могут отличается типом слушателей (listeners), которые вызываются.

Давайте начнем с рассмотрения фазы Bubbling.

Event Bubbling

Bubbling — это поток событий, при котором, сначала запускает обработчик на элементе, затем на родительском элементе и затем на всех предков элемента.

Он в основном перемещается вверх по иерархии от самого внутреннего элемента к внешнему элементу.

Это может быть лучше понято на примере —

<body>
    <div id="grandparent">
      <p>Grandparent</p>
      <div id="parent">
        <p>Parent</p>
        <div id="child">
          <p>Child</p>
        </div>
      </div>
    </div>
    <button onClick="history.go(0)">
      Reset Elements
    </button>
  </body>

В нашем HTML-файле мы берем 3 div, вложенных друг в друга, и присваиваем им идентификаторы child, parent и grandparent, начиная с самого внутреннего div.

Add a bit of styling

div {
  min-width: 75px;
  min-height: 75px;
  padding: 25px;
  border: 1px solid black;
}

button {
  margin-top: 20px;
  width: 200px;
  font-size: 14px;
  padding: 10px;
}

Мы установим обработчик событие клика для каждого из 3-х div в нашем файле JS

document.querySelector("#grandparent").addEventListener("click", () => {
  document.querySelector("#grandparent > p").textContent =
    "Grandparent Clicked!";
  console.log("Grandparent Clicked");
});

document.querySelector("#parent").addEventListener("click", () => {
  document.querySelector("#parent > p").textContent = "Parent Clicked!";
  console.log("Parent Clicked");
});

document.querySelector("#child").addEventListener("click", () => {
  document.querySelector("#child > p").textContent = "Child Clicked!";
  console.log("Child Clicked");
});

Код выше будет работать следующим образом —

Обратите внимание, что даже при клике на элементе child запускаются обработчики всех его предков. Аналогичным образом, при клике по родительскому элементу parent также будет запущен обработчик элемента grandparent родительского элемента. Но обратите внимание, что тогда обработчик дочернего элемента child не будет запущен.

Хотя здесь важнее то, как происходил поток событий. Он начинался с самого внутреннего элемента, то есть дочернего элемента child, а затем распространялся вверх по иерархии, в конечном итоге достигая элементов parent и grandparent (строго в этом порядке).

Такой тип потока событий называется Event Bubbling.

Event Capturing

Capturing является полной противоположностью bubbling.
В Event Capturing распространение события происходит от самого внешнего элемента до самого внутреннего элемента. Event Capturing иногда также называют event trickling.

Мы часто используем addEventListener() при работе с Javascript, в котором мы обычно передаем два параметра —

  • Имя события
  • Функцию обработки

Функция addEventListener() также принимает третий скрытый параметр — useCapture, который принимает логическое значение. Этот параметр useCapture по умолчанию имеет значение false. Если установить значение false, наши события будут распространяться по принципу Bubbling. Установка его в true заставит их распространяться в нисходящем подходе, то есть Capturing.

Для реализации Event Capturing мы внесем несколько небольших изменений в наш код JS —

document.querySelector("#grandparent").addEventListener("click", () => {
  document.querySelector("#grandparent > p").textContent =
    "Grandparent Clicked!";
  console.log("Grandparent Clicked");
}, true); // Параметр useCapture теперь имеет значение true

document.querySelector("#parent").addEventListener("click", () => {
  document.querySelector("#parent > p").textContent = "Parent Clicked!";
  console.log("Parent Clicked");
}, true); // Параметр useCapture теперь имеет значение true

document.querySelector("#child").addEventListener("click", () => {
  document.querySelector("#child > p").textContent = "Child Clicked!";
  console.log("Child Clicked");
}, true); // Параметр useCapture теперь имеет значение true

Теперь наш код будет работать следующим образом —

Обратите внимание, как поток событий теперь распространяется от самого внешнего элемента к самому внутреннему элементу.

то есть grandparent -> parent -> child

Такой поток событий называется Event Capturing.

Заключение

Javascript помогает нам создавать интерактивные веб-приложения. При этом используется множество пользовательских событий. Пользовательский опыт веб-сайта зависит от того, насколько хорошо эти события обрабатываются. Следовательно, важно знать, как работают события и как они движутся.

Вот ссылка на Codepen, если вы хотите увидеть это самостоятельно.

Если вам понравилось то, что вы прочитали, следите за мной в Twitter — @afraz_momin, чтобы быть в курсе новых статей.
Я планирую написать подобные статьи о JavaScript в ближайшие дни!

Была ли вам полезна эта статья?
[4 / 5]

Spread the love
Editorial Team

Recent Posts

Vue 3.4 Новая механика v-model компонента

Краткий перевод: https://vuejs.org/guide/components/v-model.html Основное использование​ v-model используется для реализации двусторонней привязки в компоненте. Начиная с Vue…

12 месяцев ago

Анонс Vue 3.4

Сегодня мы рады объявить о выпуске Vue 3.4 «🏀 Slam Dunk»! Этот выпуск включает в…

12 месяцев ago

Как принудительно пере-отобразить (re-render) компонент Vue

Vue.js — это универсальный и адаптируемый фреймворк. Благодаря своей отличительной архитектуре и системе реактивности Vue…

2 года ago

Проблемы с установкой сертификата на nginix

Недавно, у меня истек сертификат и пришлось заказывать новый и затем устанавливать на хостинг с…

2 года ago

Введение в JavaScript Temporal API

Каким бы ни было ваше мнение о JavaScript, но всем известно, что работа с датами…

2 года ago

Когда и как выбирать между медиа запросами и контейнерными запросами

Все, кто следит за последними событиями в мире адаптивного дизайна, согласятся, что введение контейнерных запросов…

2 года ago