01-Event Bubbling 1.1- Introduction to event bubblingKnowledge points in this section: Introduce what event bubbling is
element->parent element->body->html->document->window Event bubbling has always existed, but we didn't add the same event to the parent element before <!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <meta http-equiv="X-UA-Compatible" content="IE=edge"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <title>Event Bubbling</title> <style> .parent { position: relative; width: 200px; height: 200px; background-color: pink; } .son { position: absolute; left: 400px; top: 300px; width: 100px; height: 100px; background-color: red; } </style> </head> <body> <!-- Bubble: bubble --> <div class="parent"> <div class="son"></div> </div> <script> // Prove bubbling: Just add the same type of event to the parent and child const parent = document.querySelector('.parent') const son = parent.firstElementChild // Bind click events to parent and child parent.onclick = function () { console.log('parent') } // Click on the parent element: output parent, click on the son element: also output parent // 1. All elements have events: whether they are given events or not, they all have events // 2. Clicking on son triggers the click event of parent: event bubbling occurs // All elements have events, including the top-level object window window.onclick = function () { console.log('window') } // Event chain: target element -> parent -> parent -> body -> html -> document -> window // Event bubbling: most of the time useless (and bad) </script> </body> </html> 1.2-Event Bubbling Utilization (Event Delegation)Knowledge points in this section: Introduce the benefits of event bubbling Event bubbling benefits: If we want to add events to multiple child elements of a parent element, we only need to add events to the parent element, and then By getting the event source (e.target), you can know which child element triggered the event. <!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <meta http-equiv="X-UA-Compatible" content="IE=edge"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <title>Event Bubbling - Application - Event Delegation</title> <style> li { margin: 20px 0; } </style> </head> <body> <ul> <li>Baili Shouyue 1</li> <li>Baili Shouyue 2</li> <li>Baili Shouyue 3</li> </ul> <script> // Requirement: Add mouse in and out events to all li: just change the color// document.querySelectorAll('li').forEach(function (li) { // li.onmouseover = function () { // this.style.backgroundColor = 'red' // } // li.onmouseout = function () { // this.style.backgroundColor = '' // } // }) // 1. The code execution efficiency is low: all li need to be bound to events one by one // 2. Weak scalability: adding a new li will be invalid // innerHTML: all are invalid // document.querySelector('ul').innerHTML += '<li>innerHTML的li</li>' // Logic: Take out all li (structure, excluding events) in ul, and put them back in (string form): All events are lost // document.createElement() + appendChild(): New events are invalid // let li = document.createElement('li') // li.innerHTML = 'li created by creatElement' // document.querySelector('ul').appendChild(li) // Event delegation: Bind the child element's bound event (effect code) to the parent element document.querySelector('ul').onmouseover = function (e) { // In the event object: e.target is the original target that triggered the event (the topmost child) console.log(e.target) // How to distinguish whether the target element is li or ul? Node: Three elements of a node // nodeType: li and ul are both elements, 1 // nodeValue: li and element are both elements, null // nodeName: is the uppercase name of the element tag: LI UL console.log(e.target.nodeName) if (e.target.nodeName === 'LI') { // is the target element e.target.style.backgroundColor = 'red' } } document.querySelector('ul').onmouseout = function (e) { if (e.target.nodeName === 'LI') { // is the target element e.target.style.backgroundColor = '' } } // Biggest advantage: Event binding once (greatly improved performance) // Secondary advantage: Regardless of whether innerHTMl is modified or created by createElement: all li are valid // document.querySelector('ul').innerHTML += '<li>innerHTML的li</li>' // It is precisely because of event delegation: there is no need to create elements in the future, it is much more convenient to use innerHTML directly // let li = document.createElement('li') // li.innerHTML = 'li created by creatElement' // document.querySelector('ul').appendChild(li) // Event delegation: is the only value of event bubbling (very useful) </script> </body> </html> 1.3-Event bubbling influence and prevention of event bubbling
Event bubbling can lead to demand conflicts: for example, if I want to add a function, after the login window pops up, click the blank area of the body to make the login window disappear. At this time, the click event of the pop-up login window of the a tag will trigger the click event of the body, causing the login window to disappear as soon as it appears. Solution: Prevent event bubbling (knowledge point in the next section)
Prevent event bubbling: prevent events of the same name from bubbling (triggering) in parent elements * In layman's terms: Clicking an element will only trigger the event of the current element, not the event of the parent element with the same name Syntax: event object.stopPropagation() Not supported by IE8 and earlier Event object.cancelBubble = true Supported before IE8 Note: If you want to prevent event bubbling, be sure to receive the event object in the function that triggers the event <!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <meta http-equiv="X-UA-Compatible" content="IE=edge"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <title>Event Bubbling - Impact - Preventing Event Bubbling</title> <style> * { margin: 0; padding: 0; } a { text-decoration: none; display: block; width: 200px; margin: 20px auto; } .form { position: relative; width: 400px; height: 200px; margin: 0 auto; text-align: center; border: 1px solid #ccc; display: none; } .form span { display: block; position: absolute; right: -25px; top: -25px; width: 50px; height: 50px; text-align: center; line-height: 50px; border: 1px solid #ccc; border-radius: 50%; background-color: #fff; cursor: pointer; } </style> </head> <body> <a href="javascript:;" rel="external nofollow" >Click me to display the login box</a> <div class="form"> <span>X</span> Username: <input type="text" name="username"><br> Password: <input type="password" name="password"><br> <button>Login</button> </div> <script> // Event bubbling: The child element event triggers, causing the same event of the parent element to be triggered // Requirement: Click the link to display the login box, and click any blank space to hide the login box const a = document.querySelector('a') const form = document.querySelector('.form') const x = form.firstElementChild // Stop bubbling: Stop the event from being passed: event object e.stopPropagation() // If the child element does not want the parent element to trigger the same event as the child element: In the child element's event, prevent the transmission // 1. Give a click event: Display div.form a.onclick = function (e) { console.log('a') form.style.display = 'block' console.log(e) // Prevent transmission: click event, end at a e.stopPropagation() } // 2. Click on a blank to hide div.form: Simple: give document || window a click event document.onclick = function () { console.log('document') form.style.display = '' } // 3. For safety: make the entire formdiv clickable, and do not pass form.onclick = function (e) { e.stopPropagation() } // 4. Click to close x.onclick = function () { form.style.display = '' } // Summary // In actual development: The same type of events may occur in the parent and child. If the effects are opposite (a wants to display div, document wants to hide div), it is generally used to prevent event transmission: e.stopPropagation() </script> </body> </html> 02-Event Capture 1.1- Introduction to event captureKnowledge point of this section: event capture
Event capture and event bubbling trigger events in the exact opposite order
Others are bubbling (not added through addEventListener, addEventListener parameter is false)
1.2-Three stages of the eventKnowledge points in this section: Introduce the three stages of events
1 – Capture Phase:
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <meta http-equiv="X-UA-Compatible" content="IE=edge"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <title>Event Capture</title> </head> <body> <div class="box">I am Xiao Ma Ge</div> <script> // on event: all are bubbling events window.onclick = function () { console.log('window bubbling event') } document.onclick = function () { console.log('document's bubbling event') } const box = document.querySelector('.box') box.onclick = function () { console.log('box's bubbling event') } // Capture events: There is only one way addEventListener('event type', callback function, true) window.addEventListener('click', function () { // console.log('window capture event') }, true) document.addEventListener('click', function () { console.log('document capture event') }, true) // The only value of event capture: prepare for the event target // Event flow: capture first, then target, then bubble // Target phase: does not distinguish between capture and bubble (which code is in front, which one is executed first) // Latest Google: capture first, then bubble // IE is in order (target phase) // There is already a click bubble in front of the box box.addEventListener('click', function () { console.log('box capture event') }, true) // e.stopPropagation() organizes event delivery: If it is blocked in the capture phase: it will cause js bug window.addEventListener('click', function (e) { e.stopPropagation() }, true) </script> </body> </html>``` This is the end of this article about the brief analysis of event bubbling and event capture in js. For more relevant js event bubbling and event capture content, please search for previous articles on 123WORDPRESS.COM or continue to browse the following related articles. I hope you will support 123WORDPRESS.COM in the future! You may also be interested in:
|
<<: MySQL uses limit to implement paging example method
>>: How to solve the problem that the project in eclipse cannot be added to tomcat
Open Source Database Architecture Design Principl...
If we introduce the nesting rules of basic HTML w...
Upgrade process: Original system: CentOS7.3 [root...
Operation effect: html <!-- This element is no...
Effect The pictures in the code can be changed by...
Create a project directory mkdir php Create the f...
Definition of Float Sets the element out of the n...
1. Priority of multiple servers For example, if e...
Table of contents 1. Characteristics of JS 1.1 Mu...
MySQL 5.7 MySQL command line client using command...
Table of contents 1. Introduction 2. Solution Imp...
What is "Sticky Footer" The so-called &...
This article example shares the specific code of ...
Table of contents Port-related concepts: Relation...
1. Javascript returns to the previous page history...