Базовый пример события JavaScript

События в JavaScript — это события, которые могут активировать определенные функции и привести к определенному поведению. Типичным примером события является «щелчок» или «наведение курсора». Вы можете настроить прослушиватели для отслеживания этих событий, которые будут запускать желаемую функциональность.

Что такое «распространение»?

Распространение относится к тому, как события перемещаются по дереву объектной модели документа (DOM). Дерево DOM — это структура, которая содержит родительские/дочерние/родственные элементы по отношению друг к другу. Вы можете думать о распространении как об электричестве, протекающем по проводу, пока оно не достигнет пункта назначения. Событие должно проходить через каждый узел в DOM, пока не достигнет конца или не будет принудительно остановлено.

Всплывание и захват событий
Всплывание и захват — это две фазы распространения. В самом простом определении всплывание перемещается от цели к корню, а захват перемещается от root в цель. Однако это не имеет особого смысла без предварительного определения цели и корня.

Целью является узел DOM, на котором вы щелкаете или запускаете любое другое событие.

Например, кнопка с событием клика будет целью события.

root – это родительский объект самого высокого уровня. Обычно это document, который является родителем , который является (возможно, удаленным) родителем вашего целевого элемента.

Захват используется не так часто, как всплытие, поэтому наши примеры будут вращаться вокруг фазы всплытия. Однако в качестве опции EventTarget.addEventListener() имеет необязательный третий параметр, который принимает аргумент в виде логического значения, который управляет фазой распространения. Параметр называется useCapture, и передача true приведет к тому, что прослушиватель будет находиться на этапе захвата. По умолчанию используется значение false, которое применяется к фазе всплытия.

Как только вы инициируете событие, оно _распространится_ до корня и вызовет каждый отдельный обработчик событий, связанный с одним и тем же типом. Например, если у вашей кнопки есть событие щелчка, во время фазы всплытия оно будет подниматься до корня и запускать каждое событие щелчка по пути.

Такое поведение может показаться нежелательным — и часто это не так — но есть простой обходной путь…

Event.stopPropagation()
Эти два метода используются для решения ранее упомянутой проблемы, связанной с распространением событий. Вызов Event.stopPropagation() предотвратит дальнейшее распространение по дереву DOM и запустит только тот обработчик события, из которого он был вызван.

<!--Try it-->
function first() {
  console.log(1);
}
function second() {
  console.log(2);
}
let button = document.getElementById("button");
let container = document.getElementById("container");
button.addEventListener("click", first);
container.addEventListener("click", second);

В этом примере нажатие кнопки приведет к тому, что консоль напечатает 1, 2. Если бы мы хотели изменить это так, чтобы срабатывало только событие нажатия кнопки, мы могли бы использовать Event.stopPropagation(), чтобы немедленно остановить передачу события родительскому элементу.

function first(event) {
  event.stopPropagation();
  console.log(1);
}

Эта модификация позволит консоли выводить 1, но сразу же завершит цепочку событий, не позволяя ей достичь 2.

Чем это отличается от Event.stopImmediatePropagation()? Когда бы вы использовали любой из них?

<!--Try it-->
function first(event) {
  console.log(1);
}
function second() {
  console.log(2);
}
function third() {
  console.log(3);
}
let button = document.getElementById("button");
let container = document.getElementById("container");
button.addEventListener("click", first);
button.addEventListener("click", second);
container.addEventListener("click", third);

Предположим, мы хотим добавить третью функцию, которая выводит 3 в консоль. В этом сценарии мы также переместим функцию второй на кнопку. Сейчас мы применим третий к контейнеру.

Короче говоря: у нас есть два обработчика событий на кнопке, и нажатие <div#container> теперь напечатает 3.

Что произойдет сейчас? Это будет вести себя так же, как и раньше, и будет распространяться по дереву DOM и печатать 1, 2, 3 в указанном порядке.

Как это связано с Event.stopPropagation() и Event.stopImmediatePropagation()?

Добавление Event.stopPropagation() к первой функции, например так, выведет 1, 2 на консоль.

function first(event) {
  event.stopPropagation();
  console.log(1);
}

Это связано с тем, что Event.stopPropagation() немедленно предотвратит срабатывание всех событий щелчка на родительском элементе, но не остановит любое другое событие. обработчики от вызова.

Как вы можете видеть в нашем примере, у нашей кнопки есть два обработчика кликов, и она остановила распространение к своим родителям. Если вы хотите остановить все обработчики событий после первого, вам поможет Event.stopImmediatePropagation() .

function first(event) {
  event.stopImmediatePropagation();
  console.log(1);
}

Теперь первая функция действительно остановит родительские обработчики кликов и все остальные обработчики кликов. Консоль теперь будет печатать только 1, тогда как, если бы мы просто использовали Event.stopPropagation(), она напечатала бы 1, 2, не включая любой напечатает *1, 2, 3 *.

Вот оно!! #HappyCoding