Почему я не вижу несколько действий console.log (), когда всплывающее или распространяющееся вниз с помощью прослушивателя событий? - PullRequest
2 голосов
/ 29 октября 2019

const containers = document.querySelectorAll('div.container');


containers.forEach(container => {
  container.addEventListener('click', e => {
    console.log('I am fired');
  }, true);
});

// containers.forEach(container => {
//   container.addEventListener('click', e => {
//     console.log('I am fired');
//   }, false);
// });
body {
  font-family: Lato;
}

.group {
  display: flex;
  justify-content: center;
  align-items: center;
  height: 100vh;
}

.container {
  background-color: #1f1f1f;
  color: #ccc;
  display: flex;
  flex-direction: column;
  justify-content: center;
  align-items: center;
  height: 100px;
  width: 100px;
  margin: 0 30px;
  cursor: pointer;
}

.container h2 {
  margin: 0;
  margin-bottom: 5px;
}

span {
  font-size: 12px;
}
<div class="group">
  <div class="container" data-letter="A">
    <h2>A</h2>
    <span>Subtitle</span>
  </div>

  <div class="container" data-letter="B">
    <h2>B</h2>
    <span>Subtitle</span>
  </div>

  <div class="container" data-letter="C">
    <h2>C</h2>
    <span>Subtitle</span>
  </div>
</div>

Независимо от того, если я поднимаюсь или распространяюсь вниз и помещаю сообщение console.log в обработчик событий, сообщение console.log ()только один раз выстрелил. Разве он не должен срабатывать каждый раз, когда попадает в новый элемент дерева DOM?

1 Ответ

4 голосов
/ 29 октября 2019

Независимо от того, если я всплываю вверх или распространяюсь вниз и помещаю сообщение console.log в обработчик событий, сообщение console.log () срабатывает только один раз. Разве он не должен срабатывать каждый раз, когда попадает на новый элемент в дереве DOM?

Ни один из ваших div.container элементов не находится внутри других. Захват и распространение происходят в иерархиях предков / потомков, а не среди братьев и сестер или других подобных объектов.

Если вы поместите их друг в друга, вы увидите несколько сообщений:

const containers = document.querySelectorAll('div.container');


containers.forEach(container => {
  container.addEventListener('click', e => {
    console.log('I am fired');
  }, true);
});

// containers.forEach(container => {
//   container.addEventListener('click', e => {
//     console.log('I am fired');
//   }, false);
// });
body {
  font-family: Lato;
}

.group {
  display: flex;
  justify-content: center;
  align-items: center;
  height: 100vh;
}

.container {
  background-color: #1f1f1f;
  color: #ccc;
  display: flex;
  flex-direction: column;
  justify-content: center;
  align-items: center;
  height: 100px;
  width: 100px;
  margin: 0 30px;
  cursor: pointer;
}

.container h2 {
  margin: 0;
  margin-bottom: 5px;
}

span {
  font-size: 12px;
}
<div class="group">
  <div class="container" data-letter="A">
    <h2>A</h2>
    <span>Subtitle</span>
    <div class="container" data-letter="B">
      <h2>B</h2>
      <span>Subtitle</span>
      <div class="container" data-letter="C">
        <h2>C</h2>
        <span>INNERMOST - click here</span>
      </div>
    </div>
  </div>
</div>

Вот более простой пример:

const phaseName = {
    [Event.NONE]: "NONE",
    [Event.CAPTURING_PHASE]: "CAPTURING_PHASE",
    [Event.AT_TARGET]: "AT_TARGET",
    [Event.BUBBLING_PHASE]: "BUBBLING_PHASE",
};
function handler(e) {
    console.log(`div#${this.id} - ${phaseName[e.eventPhase] || "(unknown)"}`);
}
document.querySelectorAll("#container div").forEach(el => {
    el.addEventListener("click", handler, true);
    el.addEventListener("click", handler, false);
});
<div id="container">
    <div id="a">
        <div id="b">
            <div id="c">
                Click here
            </div>
        </div>
    </div>
    <div id="d">
        <div id="e">
            <div id="f">
                Or here
            </div>
        </div>
    </div>
</div>

Если вы нажмете «Нажмите здесь», вы увидите, что событие проходит вниз через #a и #b до #c, а затем снова всплывает. Он не проходит через #d, #e или #f. Если вы нажмете «Или здесь», он пройдет через эти, а не #a, #b и #c.

Подробности в спецификации DOM UI Events , которая имеет этот раздел с этой прекрасной диаграммой:

enter image description here

...