Почему этап захвата не прерывается с помощью event.stopPropagation? - PullRequest
0 голосов
/ 22 января 2019

Если вы запустите этот код и нажмете P, весь этап захвата будет выполнен, но этап барботирования будет остановлен, как и ожидалось, на div.В чем проблема с этим кодом?

  for(let elem of document.querySelectorAll('*')) {
    elem.addEventListener("click", e => alert(`Capturing: ${elem.tagName}`), true);
    elem.addEventListener("click", e => alert(`Bubbling: ${elem.tagName}`));
  }
<form>FORM
  <div onclick="event.stopPropagation()">DIV
    <p>P</p>
  </div>
</form>

1 Ответ

0 голосов
/ 22 января 2019

Фаза захвата не прерывается, потому что в современных браузерах события по умолчанию регистрируются в фазе пузырьков (поэтому событие onclick() в вашем элементе <div> не взаимодействует с отдельным обработчиком событий, который вы зарегистрировали в фазе захвата). ).

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

В приведенном ниже фрагменте приведена модифицированная версия вашего кода, которая, я думаю, является, вероятно, тем, что вы изначально планировали. Вы увидите, что этот код вызывает stopPropagation() как в обработчике фазы захвата, так и в фазе пузырьков (и приводит к ожидаемому результату в обоих случаях).

for (let elem of document.querySelectorAll('*')) {
  
  elem.addEventListener('click', (e) => {
    if (elem.tagName === 'DIV') {
      e.stopPropagation();
    }
    console.log(`Capturing: ${elem.tagName}`);
  }, true);
  
  elem.addEventListener('click', (e) => {
    if (elem.tagName === 'DIV') {
      e.stopPropagation();
    }
    console.log(`Bubbling: ${elem.tagName}`);
  });

}
<form>
  form
  <div>
    div (click here)
    <p>p</p>
  </div>
</form>

На этапе захвата браузер обрабатывает обработчики, начиная с самого внешнего родителя, поэтому он не обнаруживает stopPropagation(), пока не обработает обработчики click для всех родительских элементов <html>, <body>, и т.д.

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

...