Афоризм
Ничего страшного, если над тобой смеются. Гораздо хуже, когда над тобой плачут.
Михаил Жванецкий
Последние статьи

 • Активности Android
Многоэкранные Android приложения
 • Fragment dynamic
Динамическая загрузка фрагментов в Android
 • Fragment lifecycle
Жизненный цикл Fragment'ов в Android
 • Fragment example
Пример Fragment'ов в Android
 • Data Binding
Описание и пример Data Binding
 • Пример MVVM
Пример использования MVVM в Android
 • Компонент TreeTable
Описание компонента TreeTable для Swing
 • Пример TreeTable
Пример использования TreeTable
 • Хранилища Android
Внутренние и внешние хранилища данных
 • Пример SQLite
Пример использования SQLite в Android
 • WebSocket
Описание и пример реализации WebSocket
 • Визуальные компоненты
Улучшен компонент выбора даты из календаря
 • Анимация jQuery
Описание и примеры анимации элементов DOM
 • APK-файл Android
Создание apk-файла для android устройств, .dex файлы
 • платформа JaBricks
Платформа OSGi-приложения JaBricks
Поддержка проекта

Если Вам сайт понравился и помог, то будем признательны за Ваш «посильный» вклад в его поддержку и развитие
 • Yandex.Деньги
  410013796724260

 • Webmoney
  R335386147728
  Z369087728698
Перейти к содержанию jQuery

Всплытие событий в структуре DOM

Когда посетитель WEB-сайта нажимает на какой-либо элемент на странице, то генерируется событие нажатия. Это событие может распространяться от элемента к элементу. Например, если нажать на блок div, то будет вызван обработчик события click элемента div (при его наличии), также будет вызван обработчик body, в котором блок div находится. Таким образом происходит распространение события. Есть несколько форм распространения событий :

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

Пример перехвата событий

Рассмотрим пример html-кода, в котором 3 блока div вложены друг друга. Самый верхний уровень имеет идентификатор capt1. Элемент с идентификатором capt2 является дочерним для capt1 и включает дочерний элемент capt3. Стили представления элементов на странице я не привожу, поскольку они не имеют отношения к сути описываемого. К элементам div подключены рассмотренные ниже слушатели событий click, перехватывающие распространение низходящих и восходящих событий. Перехватчики событий открывают окно alert с идентификатором эемента. Интерфейс примера представлен на странице ниже


<div id="capt1">capt1
    <div id="capt2">capt2
        <div id="capt3">capt3</div>
    </div>
</div>
 

Если Вы нажмёте курсором мыши на зеленом элементе capt1, то 2 раза откроется окно с необходимостью подтверждения действия и с текстом «capt1». Зеленый элемент div с идентификатором capt1 является родительским для остальных. Поэтому, окно открывается только 2 раза : сначала для нисходящего распространения от body к div, после этого для восходящего от div к body (body не включает обработчик/перехватчик события). Дочерних внутренних элементов div (capt2, capt3) это распространение событий не коснулось.

При нажатии на синий элемент capt2 распространение события click по нисходящей лестнице сначала коснется родительского элемента capt1, после этого перейдет к capt2. И далее по восходящей лестнице в обратную сторону : capt2 и capt1.

capt1
capt2
capt3

Листинг скриптов

Ниже представлен листинг javascript-кода, используемого для перехвата событий. Сначала в коде локальные переменные связываются с блоками <div> методом document.getElementById. К блокам подключаются слушатели событий click функцией addEventListener. Третий логический параметр функции определяет фазу срабатывания. Если значение true, то событие будет перехватываться на фазе захвата, т.е. при погружении. При значении false событие перехватывается на фазе всплытия. В примере установлены события на обе фазы.

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


<script>
    let capt1 = document.getElementById("capt1");
    let capt2 = document.getElementById("capt2");
    let capt3 = document.getElementById("capt3");
  
    capt1.addEventListener("click", function() {
        alert('capt1') }, true);
    capt2.addEventListener("click", function() {
        alert('capt2') }, true);
    capt3.addEventListener("click", function() {
        alert('capt3') }, true);
  
    capt1.addEventListener("click", function() {
        alert('capt1') }, false);
    capt2.addEventListener("click", function() {
        alert('capt2') }, false);
    capt3.addEventListener("click", function() {
        alert('capt3') }, false);
</script>
 

Останов всплытия, stopPropagation

Всплытие вызовов можно остановить в обработчике, для этого следует вызвать метод event.stopPropagation(). Если элемент имеет несколько обработчиков одного события, то все они будут выполнены даже при прекращении всплытия. То есть, stopPropagation останавливает вызов обработчиков событий выше по цепочке, но у текущего элемента все обработчики будут выполнены. Чтобы полностью остановить обработку событий, браузеры поддерживают метод event.stopImmediatePropagation(), который останавливает обработку событий на текущем элементе, а также предотвращает всплытие.

Пример останова всплытия

Рассмотрим следующий html-код. Внутри обрамленного прямоугольником контейнера <div> с идентификатором div_emersion расположена ссылка 'a' (<a href ...>). Ниже ссылки располагается элемент <span> для отображения комментария. Таким образом, контейнер <div> является родительским по отношению к ссылке. В этом случае, при нажатии на ссылку всплывающее событие должно затронуть и контейнер. При нажатии на контейнер всплывающее событие ссылку не затронет.

<head>
    <style>
        .yellow {
           background : yellow
	    }
    </style>
</head>
<body>
<div id="div_emersion" style="border:1px solid #888">
    <p><a href="#">ссылка 'a'</a></p>
    <span id="div_span" 
          style="font-size:0.8em;font-style:italic">
    </span>
</div>
</body>
 

К элементу <div> в блоке скриптов (см. ниже) подключен обработчик, который закрашивает фон прямоугольника в желтый цвет. При повторном нажатии цвет фона восстанавливается. К ссылке также подключен обработчик, который останавливает «всплытие» события методом event.stopPropagation(). Ниже представлена реализация данного примера. Вы можете понажимать курсором мыши в разных местах блока; в комментарии будет отображаться событие.

Листинг скриптов

Скриптовый блок включает функцию document-ready, которая гарантирует выполнение сразу же после загрузки всей страницы и формирования структуры DOM. Внутри функции к ссылке подключается первый обработчик нажатия 'click', который вызывает метод останова всплытия stopPropagation и отображает в комментарии выполненное действие. К блоку <div> подключается второй обработчик, который при каждом нажатии методом toggleClass поочередно добавляет и удаляет класс 'yellow', изменяя таким образом цвет фона. Для выбора элементов DOM и подключения к ним обработчиков click используются селектор и метод find.


<script type="text/javascript">
$(document).ready(function() {
   $('#div_emersion').find('a').click(function(event) {
      event.stopPropagation();
      $('#div_emersion').find('span')
                        .text('Вы нажали на ссылку "a"');
   });

   $('#div_emersion').click(function() {
      $(this).toggleClass('yellow');
      $(this).find('span').text('Вы нажали на элемент <div>');
   });
});
</script>
 

Останов выполнения, preventDefault

В отличие от stopPropagation метод preventDefault блокирует не только всплытие события, но и выполнение текущего действия. Рассмотрим пример, интерфейс которого представлен в следующем блоке. Так, при нажатии на ссылку ничего не произойдет; ссылка блокирирована. Нажатием на кнопку ссылка может быть разблокирована; при повторном нажатии на кнопку ссылка снова блокируется. Реализация данной логики представлена в скриптовом блоке.

java-online.ru (ссылка блокирована)

Листинг html-кода

Исходный html-код примера включает два блока <div>. В первом блоке расположена ссылка, во втором – кнопка. Ссылка блокирована в скриптовом блоке (см. ниже). Нажатием на кнопку ссылку можно разблокировать и повторно заблокировать.


<div id="id_propagation" style="margin-bottom:10px">
    <a href="http://www.java-online.ru" 
       target="_blank">java-online.ru/jquery.xhtml</a>
       (ссылка блокирована)
</div>

<div>
    <button id="but">Разблокировать ссылку</button>
</div>

Листинг скриптов

Скриптовый блок включает 2 функции обработки событий click, подключенные к ссылке и к кнопке. В первой функции, подключенной к ссылке, выполняется проверка наличия у кнопки в структуре DOM класса 'propagation' методом hasClass библиотеки jQuery. Если кнопка 'but' имеет класс 'propagation', то выполнение действия блокируется методом event.preventDefault.

Во второй функции, подключенной к кнопке, при её нажатии устанавливается/сбрасывается класс 'propagation' методом toggleClass библиотеки jQuery. После этого, в зависимости от наличия в элементе класса 'propagation' устанавливаются соответствующие надписи на ссылке и кнопке.


<script>
$('#id_propagation').click(function (e) {
   if (!$('#but').hasClass('propagation'))
      // При клике на ссылку переход осуществлен не будет
      e.preventDefault();
});

$("#but").click(function (event) {
    $('#but').toggleClass('propagation');
    if ($('#but').hasClass('propagation')) {
        $('#but').html('Заблокировать ссылку');
        $('#id_propagation').html(
            <a href="http://java-online.ru" 
                target="_blank">java-online.ru</a>
               (ссылка разблокирована)");
    } else {
        $('#id_propagation').html(
            <a href="http://java-online.ru" 
                target="_blank">java-online.ru</a>
               (ссылка блокирована)");
        $('#but').html('Разблокировать ссылку');
    }
});
</script>
 

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

Связанные страницы

Описание библиотеки jQuery
Выбор элементов из объектной модели документа DOM
Фильтрация наборов и поиск элементов jQuery методами filter, find
  Рейтинг@Mail.ru