DevGang
Авторизоваться

Захват событий и бабблинг

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

Давайте попробуем разобраться в этом на самом простом примере:

<div class="A" onclick="alert('Paren1')">
   Parent 1
   <div class="B" onclick="alert('Parent')">
     Parent 2
     <div class="C" onclick="alert('Child')">Child</div>
  </div>
</div>
.A{
  height: 200px;
  width: 200px;
  background: yellow;
}

.B{
  height: 150px;
  width: 150px;
  background: green;
  margin: 0 auto;
}

.C{
  height: 100px;
  width: 100px;
  background: blue;
  margin: 0 auto;
}

Что мы ожидаем увидеть в оповещении, если мы щелкнем на дочерний элемент, должны ли также срабатывать слушатели событий для родительского элемента? И если они срабатывают, то почему это происходит?

<div class="A" onclick="alert('Paren1')">
   Parent 1
   <div class="B" onclick="alert('Parent')">
     Parent 2
     <div class="C" onclick="alert('Child')">Child</div>
  </div>
</div>

Оповещения будут отображаться в следующей последовательности:

  1. Child
  2. Parent 2
  3. Parent 1

Почему так происходит?

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

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

После целевой фазы начинается фаза бабблинга. В этой фазе событие поднимается от дочернего элемента к окну.

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

Можем ли мы выполнить обработчики в фазе захвата? Для этого мы можем установить второй параметр как true при добавлении слушателя событий к элементу.

element.addEventListener('click',handler, true);

Итак:

 <div class="A">Parent 1
    <div class="B">Parent 2
      <div class="C">Child</div>
    </div>
  </div>
.A{
  height: 200px;
  width: 200px;
  background: yellow;
}

.B{
  height: 150px;
  width: 150px;
  background: green;
  margin: 0 auto;
}

.C{
  height: 100px;
  width: 100px;
  background: blue;
  margin: 0 auto;
}
document.querySelector('.A').addEventListener('click', () => alert('Parent1'), true);
    document.querySelector('.B').addEventListener('click', () => alert('Parent2'), true);
    document.querySelector('.C').addEventListener('click', () => alert('Child'), true);

Теперь оповещения будут отображаться в следующей последовательности:

  1. Parent 1
  2. Parent 2
  3. Child

Теперь, в зависимости от конкретного случая, мы можем либо использовать логику, основанную на фазе бабблинга, либо использовать фазу захвата соответствующим образом.

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

Источник доступен по ссылке.

#JavaScript #HTML
Комментарии
Чтобы оставить комментарий, необходимо авторизоваться

Присоединяйся в тусовку

В этом месте могла бы быть ваша реклама

Разместить рекламу