JavaScript - Всплытие события

На этом уроке мы познакомимся с таким понятием как всплытие события, а также рассмотрим, как его можно прервать. Кроме этого выясним, какие ещё этапы (фазы) проходит событие, перед тем как начать всплывать.

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

JavaScript - Всплытие события

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

Всплытие события (пузырька) продемонстрируем на следующем примере:

<html>
  <head>
  </head>
  <body>
    <div>
      <h1>Заголовок</h1>
      <p>Некоторый <strong id="myElement">очень важный</strong> текст</p>
      <h2>Раздел</h2>
      <p>Некоторый текст</p>
    </div>
    <p>Остальной текст</p>
  </body>
</html>

JavaScript - Пример всплытия события

Напишем небольшой скрипт, с помощью которого добавим обработчик события "click" для всех элементов страницы, а также для объектов document и window.

<script>
document.addEventListener("DOMContentLoaded", function() {
  var allElements = document.getElementsByTagName("*");
  for (var i=0; i < allElements.length; i++) {
    allElements[i].addEventListener("click",function() {console.log(this.tagName);},false);
  };
  document.addEventListener("click",function() {console.log(this);},false);
  window.addEventListener("click",function() {console.log(this);},false);
});
</script>

Создадим HTML-страницу и вставим в неё вышеприведённый HTML код. Сценарий, написанный на языке JavaScript, вставим перед закрывающим тегом body. После этого откроем только что созданную страницу в веб-браузере, нажмём клавишу F12 и перейдём в консоль. Теперь нажмём левой кнопкой мышкой в области, принадлежащей элементу strong, и посмотрим, как событие будет всплывать.

JavaScript - Всплытие события в браузере

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

Например, изменим наш вышеприведённый пример таким образом, чтобы событие не всплывало выше body:
<script>
document.addEventListener("DOMContentLoaded", function() {
  var allElements = document.getElementsByTagName("*");
  for (var i=0; i < allElements.length; i++) {
    allElements[i].addEventListener("click",function(){
      console.log(this.tagName);
      if (this.tagName==="BODY") 
        event.stopPropagation();
    },false);
  };
  document.addEventListener("click",function() {console.log(this);},false);
  window.addEventListener("click",function() {console.log(this);},false);
});
</script>

JavaScript - Прерывание всплытия события

Бесспорно всплытие - это очень удобно и архитектурно прозрачно. Не прекращайте его без явной нужды.

Для того чтобы получить DOM-элемент (объект), который вызвал обработчик события, необходимо использовать ключевое слово this. Данное ключевое слово (this) доступно в обработчике только в том случае, если Вы подписались на событие с помощью JavaScript.

Например, выведем в консоль id элемента, который вызвал обработчик события:

var myP = document.getElementById("myP");
myP.addEventListener("click",function(){
  //получим DOM-элемент, который вызвал обработчик события - this
  //получим его id и выведем его в консоль
  console.log(this.id);
});

Для получения текущего элемента также можно использовать свойство currentTarget (event.currentTarget).

Перед тем как события начинает всплывать (этап всплытия), оно предварительно проходит ещё 2 этапа:

  • 1 этап - это этап погружения до элемента, сгенерировавшего событие. Т.е. на данном этапе происходит движение сверху вниз, т.е. от объекта window до элемента. Также данный этап ещё называют этапом перехвата.
  • 2 этап - это этап достижение цели, т.е. элемента (объекта), сгенерировавшего событие.

С учётом всех этапов, которые проходит событие, получается следующая картина:

JavaScript - Этапы (фазы) прохода события

Изменим сценарий вышеприведённого примера следующим образом:

document.addEventListener("DOMContentLoaded", function() {
  var allElements = document.getElementsByTagName("*");
  for (var i=0; i < allElements.length; i++) {
    allElements[i].addEventListener("click",function(){
      console.log(this.tagName+" Фаза: "+event.eventPhase);
    },false);
  };
  for (var i=0; i < allElements.length; i++) {
    allElements[i].addEventListener("click",function(){
      console.log(this.tagName+" Фаза: "+event.eventPhase);
    },true);
  };
  document.addEventListener("click",function() {console.log(this+" Фаза: "+event.eventPhase);},false);
  window.addEventListener("click",function() {console.log(this+" Фаза: "+event.eventPhase);},false);
  document.addEventListener("click",function() {console.log(this+" Фаза: "+event.eventPhase);},true);
  window.addEventListener("click",function() {console.log(this+" Фаза: "+event.eventPhase);},true);

JavaScript - Пример, демонстрирующий этапы (фазы) прохода события

Третий параметр методов addEventListener и removeEventListener определяет этап, на котором будет поймано событие. Если данный параметр имеет значение true, то событие будет перехватываться на стадии погружения (перехвата) события. А если параметр имеет значение false, то событие будет перехватываться на этапе всплытия. Для обработки события на самой цели, можно использовать метод addEventListener как со значением false, так и со значением true.

Внимание: на стадии погружения (перехвата), события могут перехватывать только обработчики, добавленные с помощью метода addEventListener(). Обработчики, добавленные с помощью других способов (атрибута HTML или через JavaScript с помощью свойства on[событие]) могут перехватывать события только на стадии всплытия.

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

JavaScript - Получение элемента, который сгенерировал событие

Рассмотрим вышеприведённый пример, в котором изменим содержимое элемента script на следующее:

document.addEventListener("DOMContentLoaded", function() {
  var elementBody = document.body;
  elementBody.addEventListener("click",function(){
      console.log(this.tagName + " - элемент, который вызвал обработчик");
      console.log(event.currentTarget.tagName + " - элемент, который вызвал обработчик");
      console.log(event.target.tagName + " - элемент, который сгенерировал событие");
    },false);
});

В этом примере мы добавили обработчик события "click" для элемента body. Данный обработчик будет выводить в консоль элемент, который вызвал обработчик и элемент, который сгенерировал событие.

Продемонстрируем наш пример, кликнув левой кнопкой мыши в области, принадлежащей элементу strong:

JavaScript - Пример получения элемента, который сгенерировал событие



   JavaScript и jQuery 0    1776 0

Комментарии (0)

    Вы должны авторизоваться, чтобы оставлять комментарии.