English | 简体中文 | 繁體中文 | Русский язык | Français | Español | Português | Deutsch | 日本語 | 한국어 | Italiano | بالعربية
Event propagation is a method to describe the 'event stack' triggered in a web browser.
eventBubblingandCaptureare two mechanisms of event propagation, which describe what happens when two handlers of the same event type are activated on an element.
Assuming you are in<div >element contains a<p>element, and the user clicked<p>element, should you first handle the 'click' event of which element?
<div id="div1">Capturing <p id="p1">Click me</p>" </div>" <script> document.querySelector("#div1).addEventListener("click", myFunc, true); document.querySelector("#p"}1).addEventListener("click", myFunc, true); </script>Test See‹/›
Bycapture(capture), the event is first captured by the outermost element and then propagated to the inner elements.
ByBubbling, the event is first captured and processed by the innermost element, and then propagated to the outer elements.
using theaddEventListener()method, you can use " useCapture The parameter specifies the propagation type, and the following syntax item provides a detailed explanation of useCapture.
element.addEventListener(event, listener, useCapture)
"useCapture" is set to false by default, which will use bubbling propagation by default; while setting the value to true, the event will use capturing propagation.
The concept of event propagation is introduced to handle the case where multiple elements with parent-child relationships in the DOM hierarchy have event handlers for the same event (for example, mouse clicks). The problem now is, when the user clicks an internal element, which element's click event will be processed first, that is, the external element or the internal element's click event.
When an event is triggered on an element with parent elements (for example, in this example,<p>), and the browser will run two different phases-Capture phase and bubbling phase.
InCapturePhase:
The browser will check the outermost parent element (<html>whether it has registered an onclick event handler in the capture phase, and if so, runs the event handler.
Then, it moves towithin <html>the next element and performs the same operation, then proceeds to the next, and so on, until it reaches the element that was actually clicked.
InBubblingphase, on the contrary:
The browser checks if the element actually clicked during the bubbling phase has an onclick event handler registered on it, and if so, runs the event handler.
Then, it moves to the next direct parent element and performs the next, and so on, until it reaches<html>to the element.
By default in most browsers, all event handlers are registered in the bubbling phase.
In the capture phase, the event propagates from the Window down through the DOM tree to the target node.
document.querySelector("div").addEventListener("click", myFunc, true); document.querySelector("p").addEventListener("click", myFunc, true); document.querySelector("a").addEventListener("click", myFunc, true);Test See‹/›
Only whenaddEventListener()The third parameter is set to true for event capturing to be used with the event handlers registered at the same time.
In the bubbling phase, exactly the opposite. In this phase, the event will propagate or bubble up from the target element to the Window, propagating up the DOM tree.
document.querySelector("div").addEventListener("click", myFunc); document.querySelector("p").addEventListener("click", myFunc); document.querySelector("a").addEventListener("click", myFunc);Test See‹/›
All browsers support event bubbling, and event bubbling applies to all handlers, regardless of how they are registered (e.g., using onclick or addEventListener()).
If you want to prevent any ancestor element's event handler from being notified of the event using the event.stopPropagation() method, you can also stop the event propagation in the middle.
In the following example, if you click a child element, the click event listener on the parent element will not be executed:
document.querySelector("div").addEventListener("click", myFunc); document.querySelector("p").addEventListener("click", myFunc); document.querySelector("a").addEventListener("click", myFunc); function myFunc() { alert("You clicked: ");+ this.tagName); event.stopPropagation(); }Test See‹/›
The target element is the DOM node that has generated the event.
For example, if the user clicks a hyperlink, the target element is the hyperlink.
The access method for the target element is event.target, and it will not change during the event propagation phase.
document.querySelector("div").addEventListener("click", myFunc); document.querySelector("p").addEventListener("click", myFunc); document.querySelector("a").addEventListener("click", myFunc); function myFunc() { alert("target = "); + event.target.tagName); }Test See‹/›
Certain events have associated default actions. For example, if you click a link, the browser will take you to the link's target, when you click a form submit button, the browser will submit the form, and so on. You can use the event.preventDefault() method of the event object to prevent such default actions.
function myFunc() { event.preventDefault(); }Test See‹/›
However, preventing the default action does not prevent the event from propagating; the event continues to propagate normally to the DOM tree.
Bubble also allows us to utilize event delegation.
Event delegation allows you to avoid adding event listeners to specific nodes; instead, you add event listeners to a parent object.
This concept is based on the following fact: If you want to run some code when clicking any element among a large number of child elements, you can set an event listener on the parent element and let the event bubble up to the parent element, without having to set an event listener for each child separately.
In this example, if you want to pop up a message when clicked, you can set an event listener on the parent<ul>Set a click event listener on the parent, which will pop up the list item
<ul id="parent-list"> <li id="post-1">Item 1</li> <li id="post-2">Item 2</li> <li id="post-3">Item 3</li> <li id="post-4">Item 4</li> <li id="post-5">Item 5</li> <li id="post-6">Item 6</li> </ul> <script> document.getElementById("parent-list").addEventListener("click", function(event) { if(event.target && event.target.nodeName == "LI") { alert("List item " + event.target.id.replace("post-", "") + " was clicked!"); } }); </script>Test See‹/›