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

Events are actions or occurrences that happen in the system you are programming, which the system tells you about so you can respond to them in some way if desired. For example, if the user clicks a button on a webpage, you might want to respond to that action by displaying an information box. In this article, we discuss some important concepts surrounding events, and look at how they work in browsers. This won"t be an exhaustive study; just what you need to know at this stage.

Prerequisites: Objective:
Basic computer literacy, a basic understanding of HTML and CSS, JavaScript first steps .
To understand the fundamental theory of events, how they work in browsers, and how events may differ in different programming environments.
A series of fortunate events

As mentioned above, events are actions or occurrences that happen in the system you are programming - the system produces (or "fires") a signal of some kind when an event occurs, and also provides a mechanism by which some kind of action can be automatically taken (that is, some code running) when the event occurs. For example in an airport when the runway is clear for a plane to take off, a signal is communicated to the pilot, and as a result, they commence piloting the plane.

In the case of the Web, events are fired inside the browser window, and tend to be attached to a specific item that resides in it - this might be a single element, set of elements, the HTML document loaded in the current tab, or the entire browser window. There are a lot of different types of events that can occur, for example:

  • The user clicking the mouse over a certain element or hovering the cursor over a certain element.
  • The user pressing a key on the keyboard.
  • The user resizing or closing the browser window.
  • A form being submitted.
  • A video being played, or paused, or finishing play.
  • An error occurring.

You can gather from this (and from glancing at the MDN Event reference) that there are a lot of events that can be responded to.

Each available event has an event handler , which is a block of code (usually a JavaScript function that you as a programmer create) that will be run when the event fires. When such a block of code is defined to be run in response to an event firing, we say we are registering an event handler . Note that event handlers are sometimes called event listeners - they are pretty much interchangeable for our purposes, although strictly speaking, they work together. The listener listens out for the event happening, and the handler is the code that is run in response to it happening.

Note : Web events are not part of the core JavaScript language - they are defined as part of the APIs built into the browser.

A simple example

Let"s look at a simple example to explain what we mean here. You"ve already seen events and event handlers used in many of the examples in this course already, but let"s recap just to cement our knowledge. In the following example, we have a single , which when pressed, makes the background change to a random color:

Change color

Button { margin: 10px };

The JavaScript looks like so:

Const btn = document.querySelector("button"); function random(number) { return Math.floor(Math.random() * (number+1)); } btn.onclick = function() { const rndCol = "rgb(" + random(255) + "," + random(255) + "," + random(255) + ")"; document.body.style.backgroundColor = rndCol; }

In this code, we store a reference to the button inside a constant called btn , using the Document.querySelector() function. We also define a function that returns a random number. The third part of the code is the event handler. The btn constant points to a element, and this type of object has a number of events that can fire on it, and therefore, event handlers available. We are listening for the click event firing, by setting the onclick event handler property to equal an anonymous function containing code that generates a random RGB color and sets the background-color equal to it.

This code is run whenever the click event fires on the element, that is, whenever a user clicks on it.

The example output is as follows:

It"s not just web pages

Another thing worth mentioning at this point is that events are not unique to JavaScript - most programming languages have some kind of event model, and the way the model works often differs from JavaScript"s way. In fact, the event model in JavaScript for web pages differs from the event model for JavaScript as it is used in other environments.

Inline event handlers - don"t use these

You might also see a pattern like this in your code:

Press me function bgChange() { const rndCol = "rgb(" + random(255) + "," + random(255) + "," + random(255) + ")"; document.body.style.backgroundColor = rndCol; }

The earliest method of registering event handlers found on the Web involved event handler HTML attributes (or inline event handlers ) like the one shown above - the attribute value is literally the JavaScript code you want to run when the event occurs. The above example invokes a function defined inside a element on the same page, but you could also insert JavaScript directly inside the attribute, for example:

Press me

You can find HTML attribute equivalents for many of the event handler properties; however, you shouldn"t use these - they are considered bad practice. It might seem easy to use an event handler attribute if you are just doing something really quick, but they very quickly become unmanageable and inefficient.

For a start, it is not a good idea to mix up your HTML and your JavaScript, as it becomes hard to parse - keeping your JavaScript all in one place is better; if it is in a separate file you can apply it to multiple HTML documents.

Even in a single file, inline event handlers are not a good idea. One button is OK, but what if you had 100 buttons? You"d have to add 100 attributes to the file; it would very quickly turn into a maintenance nightmare. With JavaScript, you could easily add an event handler function to all the buttons on the page no matter how many there were, using something like this:

Const buttons = document.querySelectorAll("button"); for (let i = 0; i < buttons.length; i++) { buttons[i].onclick = bgChange; } buttons.forEach(function(button) { button.onclick = bgChange; });

Note : Separating your programming logic from your content also makes your site more friendly to search engines.

addEventListener() and removeEventListener()

The newest type of event mechanism is defined in the Document Object Model (DOM) Level 2 Events Specification, which provides browsers with a new function - addEventListener() . This functions in a similar way to the event handler properties, but the syntax is obviously different. We could rewrite our random color example to look like this:

Const btn = document.querySelector("button"); function bgChange() { const rndCol = "rgb(" + random(255) + "," + random(255) + "," + random(255) + ")"; document.body.style.backgroundColor = rndCol; } btn.addEventListener("click", bgChange);

Inside the addEventListener() function, we specify two parameters - the name of the event we want to register this handler for, and the code that comprises the handler function we want to run in response to it. Note that it is perfectly appropriate to put all the code inside the addEventListener() function, in an anonymous function, like this:

Btn.addEventListener("click", function() { var rndCol = "rgb(" + random(255) + "," + random(255) + "," + random(255) + ")"; document.body.style.backgroundColor = rndCol; });

This mechanism has some advantages over the older mechanisms discussed earlier. For a start, there is a counterpart function, removeEventListener() , which removes a previously added listener. For example, this would remove the listener set in the first code block in this section:

Btn.removeEventListener("click", bgChange);

This isn"t significant for simple, small programs, but for larger, more complex programs it can improve efficiency to clean up old unused event handlers. Plus, for example, this allows you to have the same button performing different actions in different circumstances - all you have to do is add or remove event handlers as appropriate.

Second, you can also register multiple handlers for the same listener. The following two handlers wouldn"t both be applied:

MyElement.onclick = functionA; myElement.onclick = functionB;

The second line overwrites the value of onclick set by the first line. This would work, however:

MyElement.addEventListener("click", functionA); myElement.addEventListener("click", functionB);

Both functions would now run when the element is clicked.

In addition, there are a number of other powerful features and options available with this event mechanism. These are a little out of scope for this article, but if you want to read up on them, have a look at the addEventListener() and removeEventListener() reference pages.

What mechanism should I use?

Of the three mechanisms, you definitely shouldn"t use the HTML event handler attributes - these are outdated, and bad practice, as mentioned above.

The other two are relatively interchangeable, at least for simple uses:

  • Event handler properties have less power and options, but better cross-browser compatibility (being supported as far back as Internet Explorer 8). You should probably start with these as you are learning.
  • DOM Level 2 Events (addEventListener() , etc.) are more powerful, but can also become more complex and are less well supported (supported as far back as Internet Explorer 9). You should also experiment with these, and aim to use them where possible.

The main advantages of the third mechanism are that you can remove event handler code if needed, using removeEventListener() , and you can add multiple listeners of the same type to elements if required. For example, you can call addEventListener("click", function() { ... }) on an element multiple times, with different functions specified in the second argument. This is impossible with event handler properties because any subsequent attempts to set a property will overwrite earlier ones, e.g.:

Element.onclick = function1; element.onclick = function2; etc.

Note : If you are called upon to support browsers older than Internet Explorer 8 in your work, you may run into difficulties, as such ancient browsers use different event models from newer browsers. But never fear, most JavaScript libraries (for example jQuery) have built-in functions that abstract away cross-browser differences. Don"t worry about this too much at this stage in your learning journey.

Other event concepts

In this section, we briefly cover some advanced concepts that are relevant to events. It is not important to understand these concepts fully at this point, but they might serve to explain some code patterns you"ll likely come across from time to time.

Event objects

Sometimes inside an event handler function, you might see a parameter specified with a name such as event , evt , or simply e . This is called the event object , and it is automatically passed to event handlers to provide extra features and information. For example, let"s rewrite our random color example again slightly:

Function bgChange(e) { const rndCol = "rgb(" + random(255) + "," + random(255) + "," + random(255) + ")"; e.target.style.backgroundColor = rndCol; console.log(e); } btn.addEventListener("click", bgChange);

Here you can see that we are including an event object, e , in the function, and in the function setting a background color style on e.target - which is the button itself. The target property of the event object is always a reference to the element that the event has just occurred upon. So in this example, we are setting a random background color on the button, not the page.

Note : You can use any name you like for the event object - you just need to choose a name that you can then use to reference it inside the event handler function. e / evt / event are most commonly used by developers because they are short and easy to remember. It"s always good to be consistent - with yourself, and with others if possible.

e.target is incredibly useful when you want to set the same event handler on multiple elements and do something to all of them when an event occurs on them. You might, for example, have a set of 16 tiles that disappear when they are clicked on. It is useful to always be able to just set the thing to disappear as e.target , rather than having to select it in some more difficult way. In the following example (see useful-eventtarget.html for the full source code; also see it running live here), we create 16 elements using JavaScript. We then select all of them using document.querySelectorAll() , then loop through each one, adding an onclick handler to each that makes it so that a random color is applied to each one when clicked:

Const divs = document.querySelectorAll("div"); for (let i = 0; i < divs.length; i++) { divs[i].onclick = function(e) { e.target.style.backgroundColor = bgChange(); } }

The output is as follows (try clicking around on it - have fun):

Hidden example Useful event target example div { height: 100px; width: 25%; float: left; } for (let i = 1; i
  • Pencil
  • Pen
  • Eraser

  • Теперь, зная, что любое нажатие на кнопке всплывет через элемент ul.toolbar , давайте прикрепим наш обработчик событий на него. К счастью, он у нас уже есть:

    Var toolbar = document.querySelector(".toolbar"); toolbar.addEventListener("click", function(e) { var button = e.target; if(!button.classList.contains("active")) button.classList.add("active"); else button.classList.remove("active"); });
    Теперь мы имеем намного более чистый код, и мы даже избавились от циклов! Заметьте однако, что мы заменили e.currentTarget на e.target . Причина кроется в том, что мы обрабатываем события на другом уровне.

    e.target - фактическая цель события, то, куда оно пробирается через DOM, и откуда потом будет всплывать.
    e.currentTarget - текущий элемент, который обрабатывает событие. В нашем случае, это ul.toolbar .

    Улучшенные всплывающие события В данный момент мы обрабатываем любое нажатие на каждый элемент, которое всплывает через ul.toolbar , но наше условие проверки слишком простое. Что произошло бы, если бы имели более сложный DOM, включащий в себя иконки и элементы, которые не были созданы для того, чтобы по ним кликали?

    • Pencil
    • Pen
    • Eraser

    Упс! Теперь, когда мы кликаем на li.separator или иконку, мы добавляем ему класс .active . Как минимум, это нехорошо. Нам нужен способ фильтровать события так, чтобы мы реагировали на нужный нам элемент.

    Создадим для этого небольшую функцию-помощника:

    Var delegate = function(criteria, listener) { return function(e) { var el = e.target; do { if (!criteria(el)) continue; e.delegateTarget = el; listener.apply(this, arguments); return; } while((el = el.parentNode)); }; };
    Наш помощник делает две вещи. Во-первых, он обходит каждый элемент и его родителей и проверят, удовлетворяют ли они условию, переданному в параметре criteria . Если элемент удовлетворяет - помощник добавляет объекту события поле, называемое delegateTarget , в котором хранится элемент, удовлевторяющий нашим условиям. И затем вызывает обработчик. Соответственно, если ни один элемент не удовлетворяет условию, ни один обработчик не будет вызван.

    Мы можем использовать это так:

    Var toolbar = document.querySelector(".toolbar"); var buttonsFilter = function(elem) { return elem.classList && elem.classList.contains("btn"); }; var buttonHandler = function(e) { var button = e.delegateTarget; if(!button.classList.contains("active")) button.classList.add("active"); else button.classList.remove("active"); }; toolbar.addEventListener("click", delegate(buttonsFilter, buttonHandler));
    То, что доктор прописал: один обработчик событий, прикрепленный к одному элементу, который делает всю работу. Но делает ее только для нужных нам элементов. И он отлично реагирует на добавление и удаление объектов из DOM.

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

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

    Функция-помощник для проверки удовлетворения объекта критериям в более унифицированном и функциональном виде. Вроде:

    Var criteria = { isElement: function(e) { return e instanceof HTMLElement; }, hasClass: function(cls) { return function(e) { return criteria.isElement(e) && e.classList.contains(cls); } } // Больше критериев };
    Частичное использование помощника так же было бы не лишним:

    Var partialDelgate = function(criteria) { return function(handler) { return delgate(criteria, handler); } };
    Оригинал статьи: Understanding Delegated JavaScript Events
    (От переводчика: мой первый, судите строго.)

    Счастливого кодинга!

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

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

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

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

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

    Заголовок

    Некоторый очень важный текст

    Раздел

    Некоторый текст

    Остальной текст

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

    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); });

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

    Как прервать всплытие события

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

    Например, изменим наш вышеприведённый пример таким образом, чтобы событие не всплывало выше body: document.addEventListener("DOMContentLoaded", function() { var allElements = document.getElementsByTagName("*"); for (var i=0; i

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

    Получение элемента, который вызвал обработчик

    Для того чтобы получить 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 этап - это этап достижение цели, т.е. элемента (объекта), сгенерировавшего событие.

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

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

    Document.addEventListener("DOMContentLoaded", function() { var allElements = document.getElementsByTagName("*"); for (var i=0; i

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

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

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

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

    Рассмотрим вышеприведённый пример, в котором изменим содержимое элемента 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); });

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

    Перехват события

    Одна из важных особенностей языка - перехват события. Если кто-то, к примеру, щелкает на кнопке, то вызывается программа обработки события onClick, соответствующая этой кнопке. С помощью обработки событий Вы можете добиться того, чтобы объект, соответсвующий вашему окну, документу или слою, перехватывал и обрабатывал событие еще до того, как для этой цели объектом указанной кнопки будет вызван обработчик событий. Точно так же объект вашего окна, документа или слоя может обрабатывать сигнал о событии еще до того, как он достигает своего обычного адресата.
    Чтобы увидеть, для чего это может пригодиться, давайте рассмотрим следующий пример:



    window.onclick= handle;

    function handle(e) {­
    alert("Объект window перехватывает это событие!");
    return true; // т.е. проследить ссылку
    }




    Click on this link

    Как видно, мы не указываем программы обработки событий в тэге . Вместо этого мы пишем

    window.captureEvents(Event.CLICK);

    с тем, чтобы перехватить событие Click объектом window. Обычно объект window не работает с событием Click . Однако, перехватив, мы затем его переадресуем в объект window. Заметим, что в Event.CLICK фрагмент CLICK должен писаться заглавными буквами. Если же Вы хотите перехватывать несколько событий, то Вам следует отделить их друг от друга символами |. Например:

    window.captureEvents(Event.CLICK | Event.MOVE);

    Помимо этого в функции handle() , назначенной нами на роль обработчика событий, мы пользуемся инструкцией return true; . В действительности это означает, что браузер должен обработать и саму ссылку, после того, как завершится выполнение функции handle() . Если же Вы напишете вместо этого return false; , то на этом все и закончится.

    Если теперь в тэге Вы зададите программу обработки события onClick , то поймете, что данная программа при возникновении данного события вызвана уже не будет. И это не удивительно, поскольку объект window перехватывает сигнал о событии еще до того, как он достигает объекта link. Если же Вы определите функцию handle() как

    function handle(e) {­
    alert("The window object captured this event!");
    window.routeEvent(e);
    return true;
    }

    то компьютер будет проверять, определены ли другие программы обработки событий для данного объекта. Переменная e - это наш объект Event, передаваемый функции обработки событий в виде аргумента.

    Кроме того, Вы можете непосредственно послать сигнал о событии какому-либо объекту. Для этого Вы можете воспользоваться методом handleEvent() . Это выглядит следующим образом:


    window.captureEvents(Event.CLICK);

    window.onclick= handle;

    function handle(e) {­
    document.links.handleEvent(e);
    }


    "Кликните" по этой ссылке

    Вторая ссылка

    Все сигналы о событиях Click, посылаются на обработку по второй ссылке - даже если Вы вовсе и не щелкнули ни по одной из ссылок!

    Следующий скрипт демонстрирует, как Ваш скрипт может реагировать на сигналы о нажатии клавиш. Нажмите на какую-либо клавишу и посмотрите, как работает этот скрипт.


    window.captureEvents(Event.KEYPRESS);

    window.onkeypress= pressed;

    function pressed(e) {­
    alert("Key pressed! ASCII-value: " + e.which);
    }

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

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

    Этот обработчик для сработает, если вы кликните по вложенному тегу или :

    Кликните на EM, сработает обработчик на DIV

    Как видите при клике на вложенном элементе em срабатывает обработчик на div. Почему так происходит? Читайте дальше и узнаете.

    Всплытие

    Итак основной принцип всплытия:

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

    Например, пусть имеется 3 вложенных элемента FORM > DIV > P, с обработчиком собьытия на каждом:

    body * { margin: 10px; border: 1px solid blue; } FORM DIV

    Всплытие гарантирует, что клик по внутреннему элементу

    Вызовет обработчик click (если он конечно есть) сначала на самом

    Такой процесс называется всплытием, потому что события как бы «всплывают» от внутреннего элемента вверх через своих родителей, подобно тому, как всплывает пузырек воздуха в воде, поэтому можно встретить еще определение бабблинг ну это просто от английского слова bubbling — всплывать.

    Доступ к целевому элементу event.target

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

    • event.target – это собственно исходный элемент, на котором и произошло событие.
    • this – это всегда текущий элемент, до которого дошло всплытие, и на нём сейчас выполняется обработчик.

    Например, если у вас установлен только один обработчик form.onclick, то он и «поймает» все клики внутри формы. При этом где бы ни был клик внутри – он все равно всплывёт до элемента , на котором и сработает уже обработчик.

    При этом:

    • this (=event.currentTarget) всегда будет сама форма, так как обработчик сработал именно на ней.
    • event.target будет содержать ссылку на конкретный элемент внутри формы, самый вложенный, на котором произошёл клик.

    В принципе this может совпадать с event.target если кликнули по форме и в форме больше нет никаких элементов.

    Прекращение всплытия

    Как правило всплытие события идет прямо наверх и доходит до корневого объекта window.

    Но есть возможность остановить всплытие на каком-то промежуточном элементе.

    Для того, чтобы остановить всплытие надо вызвать метод event.stopPropagation().

    Рассмотрим пример, при клике на кнопку обработчик body.onclick не сработает:

    Кликни меня

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

    Таким образом, stopPropagation будет препятствует распространению события дальше, но на элементе все обработчики отработают, а вот дальше на следующем элементе уже нет.

    Для того, чтобы остановить обработку на текщем элементе, браузеры поддерживают метод event.stopImmediatePropagation(). Этот метод не только предотвратит всплытие, но и останавит обработку событий на текущем элементе.

    Погружение

    В стандарте, кроме «всплытия» событий, есть ещё и «погружение».

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

    Итак имеются 3 стадии прохода события:

  • Событие идет сверху вниз. Эта стадия называется «стадия перехвата».
  • Событие достигло конкретного элемента. Это – «стадия цели».
  • После всего событие начинает всплывать. Это – «стадия всплытия».
  • В стандарте это продемонстрировано так:

    Таким образомь, при клике на TD событие будет путешествовать по цепочке родителей сначала вниз к элементу («погружается»), а потом наверх («всплывает»), по пути соотвественно задействуя обработчики.

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

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

    А Чтобы поймать событие на стадии перехвата, как раз и нужно использовать :

    • Аргумент true, то событие будет перехвачено по дороге вниз.
    • Аргумент false, то событие будет поймано при всплытии.
    Примеры

    В примере на , ,

    Стоят те же обработчики, что и раньше, но на сей раз – на стадии погружения. Ну а чтобы увидеть перехват в действии, кликните в нём на элементе

    Обработчики сработают в порядке «сверху-вниз»: FORM → DIV → P.

    JS-код здесь такой:

    Var elems = document.querySelectorAll("form,div,p"); // на каждый элемент повесим обработчик на стадии перехвата for (var i = 0; i < elems.length; i++) { elems[i].addEventListener("click", highlightThis, true); }


    Никто вам не мешает назначить обработчики для обеих стадий, вот так:

    Var elems = document.querySelectorAll("form,div,p"); for (var i = 0; i < elems.length; i++) { elems[i].addEventListener("click", highlightThis, true); elems[i].addEventListener("click", highlightThis, false); }

    Кликните по внутреннему элементу

    Чтобы увидеть порядок прохода события:
    Должно быть FORM → DIV → P → P → DIV → FORM. Заметим, что элемент

    Будет участвовать в обоих стадиях.

    Итоги
    • При наступлении события – элемент, на котором произошло событие, помечается как event.target.
    • Событие сначала двигается вниз от корня документа к event.target, по пути вызывая обработчики, поставленные через addEventListener(…., true).
    • Событие двигается от event.target вверх до начала документа, по пути оно вызывает обработчики, поставленные через addEventListener(…., false).

    Каждый обработчик будет иметь доступ к свойствам события:

    • event.target – самый глубокий элемент, на котором собственно и произошло событие.
    • event.currentTarget (=this) – элемент, на котором в данный момент сработал самобработчик (до которого «дошло» событие).
    • event.eventPhase – на какой фазе сработал обработчик события (погружение =1, всплытие = 3).

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