@ About the sequence of event capture and event bubbling
create by db on 2021-2-21 14:33:31
Recently revised in 2021-2-21 16:00:35Have a tight mind in your spare time , When you are busy, have a leisurely interest
Preface
I hear and I fogorget.
I see and I remember.
I do and I understand.
As a front-end Developer ,DOM Is one of our most familiar partners —— Every day F11 You can see it .
however , Do you really understand it ? Can you describe the sequence of event capture and event bubbling ?
If I can't remember for a moment , Let's go and have a look .
Text
DOM The three stages of event flow
Events are propagated between element nodes in a specific order when they occur , This communication process is DOM Flow of events
When one DOM When the event is triggered , It's not just triggered once on its own object , It's going through three different stages :
- Capture phase (Capture Phase):
- When we're in DOM Something happened to a node of the tree ( For example, click 、 Mouse over ), There will be an event launched in the past . This incident started from Window issue , Continue to pass through the lower nodes until the target node is triggered . The process before reaching the target node , It's the capture phase (Capture Phase).( All the nodes that pass through , Will trigger this event . The task of the capture phase is to establish the event routing , So that the later bubbling stage can follow this route back Window.) The capture event handler registered on the target element object itself is not called .
- Target stage (Target Phase):
- When events continue to pass to the target node , Finally, this event is triggered on the target node , It's the goal stage .
- bubbling phase (Bubbling Phase):
- Then trace back from the target event location to the root node of the document , Bubbling event objects from the inside out ( The event binding we usually use is the principle of event bubbling )
As shown in the figure :
The sequence of event capture and event bubbling is obvious .
DOM Element binding js The way of the event :
onclick
stay html Tag or by assignment onclick
event , rewrite onclick
Will override the previous properties , Only bubble phase is supported , There is no compatibility issue
The binding event :element.onclick = function(){}
Unbind event :element.onclick = null
addEventListener
IE8 The following is not supported , Belong to DOM2 Level method , You can add multiple methods that are not overridden
Parameter description :
-
event
, must . character string , Specify the event name . Do not use "on" Prefix . for example , Use "click" , Instead of using "onclick". -
function
must . Specifies the function to be executed when the event is triggered , Note that only the function name is written , No parentheses . -
useCapture
Optional . Boolean value , Specifies whether the event is executed during the capture or bubble phase .
The binding event :
element.addEventListener(
'click',
function (e) {
e.preventDefault() // Block default events
},
false
)
Copy code
Unbind event :
element.removeEventListener('click',function(){},false)
attachEvent
IE specific , compatible IE8 Up to , You can add multiple event handlers , Only bubble phase is supported
Parameter description :
event
, must . character string , Specify the event name . Pay attention to the... In front of the event “on”, such as “onclick” and “onmouseover”, This is theaddEventListener
The difference between .function
The event listener function to bind , Note that only the function name is written , No parentheses .
The binding event :
element.attachEvent('onclick', function (e) {
e.returnValue = false // Block default events
})
Copy code
Unbind event : element.detachEvent("onclick",function(){})
Code up , Experimentalize
open Online editor ---> jsbin.com/cedorat/edi…
The code is as follows :
</html>
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<style>
#outer {
text-align: center;
width: 400px;
height: 400px;
background-color: yellow;
margin: 0 auto;
}
#middle {
width: 250px;
height: 250px;
background-color: red;
margin: 0 auto;
}
#inner {
width: 100px;
height: 100px;
background-color: green;
margin: 0 auto;
}
</style>
</head>
<body>
<div id='outer'>
<span>outer</span>
<div id='middle'>
<span>middle</span>
<div id='inner'>
<span>inner</span>
</div>
</div>
</div>
<script>
// First bind all capture events, then bind all bubble events
on("outer", "click", o_click_c, true);
on("middle", "click", m_click_c, true);
on("inner", "click", i_click_c, true);
on("outer", "click", o_click_b, false);
on("middle", "click", m_click_b, false);
on("inner", "click", i_click_b, false);
// // First bind all bubble events, then bind all capture events
// on("outer", "click", o_click_b, false);
// on("middle", "click", m_click_b, false);
// on("inner", "click", i_click_b, false);
// on("outer", "click", o_click_c, true);
// on("middle", "click", m_click_c, true);
// on("inner", "click", i_click_c, true);
// One by one binding capture and bubble events
// on("outer", "click", o_click_c, true);
// on("outer", "click", o_click_b, false);
// on("middle", "click", m_click_c, true);
// on("middle", "click", m_click_b, false);
// on("inner", "click", i_click_c, true);
// on("inner", "click", i_click_b, false);
// Bind bubble and capture events one by one
// on("outer", "click", o_click_b, false);
// on("outer", "click", o_click_c, true);
// on("middle", "click", m_click_b, false);
// on("middle", "click", m_click_c, true);
// on("inner", "click", i_click_b, false);
// on("inner", "click", i_click_c, true);
// Select the appropriate element
function $(element) {
return document.getElementById(element);
}
// Binding method
function on(element, event_name, handler, use_capture) {
if (addEventListener) { // All major browsers , except IE 8 And earlier IE edition
$(element).addEventListener(event_name, handler, use_capture);
} else { // IE 8 And earlier IE edition
$(element).attachEvent('on' + event_name, handler);
}
}
function o_click_c() {
console.log("outer_ Capture ");
}
function m_click_c() {
console.log("middle_ Capture ")
}
function i_click_c() {
console.log("inner_ Capture ")
}
function o_click_b() {
console.log("outer_ Bubbling ")
}
function m_click_b() {
console.log("middle_ Bubbling ")
}
function i_click_b() {
console.log("inner_ Bubbling ")
}
</script>
</body>
</body>
</html>
Copy code
In the above code , We define four execution orders :
-
First bind all capture events, then bind all bubble events
-
First bind all bubble events, then bind all capture events
-
One by one binding capture and bubble events
-
Bind bubble and capture events one by one
One 、 First bind all capture events, then bind all bubble events
Let's run the first one first :
- Click on outer, Print the results :
"outer_ Capture "
"outer_ Bubbling "
Copy code
- Click on middle, Print the results :
"outer_ Capture "
"middle_ Capture "
"middle_ Bubbling "
"outer_ Bubbling "
Copy code
- Click on inner, Print the results :
"outer_ Capture "
"middle_ Capture "
"inner_ Capture "
"inner_ Bubbling "
"middle_ Bubbling "
"outer_ Bubbling "
Copy code
Conclusion :
- First, capture events from outside to inside , All the way to the incident element , And then bubble from the inside out to the root node
Two 、 First bind all bubble events, then bind all capture events
Let's run the second one first :
- Click on outer, Print the results :
"outer_ Bubbling "
"outer_ Capture "
Copy code
- Click on middle, Print the results :
"outer_ Capture "
"middle_ Bubbling "
"middle_ Capture "
"outer_ Bubbling "
Copy code
- Click on inner, Print the results :
"outer_ Capture "
"middle_ Capture "
"inner_ Bubbling "
"inner_ Capture "
"middle_ Bubbling "
"outer_ Bubbling "
Copy code
Conclusion :
-
In the capture phase, events are captured from outside to inside , In the bubbling phase, bubbles from the inside out to the root node
-
The target element first performs the bubble event , Then execute the capture event
3、 ... and 、 One by one binding capture and bubble events
Let's run the third one first :
- Click on outer, Print the results :
"outer_ Capture "
"outer_ Bubbling "
Copy code
- Click on middle, Print the results :
"outer_ Capture "
"middle_ Capture "
"middle_ Bubbling "
"outer_ Bubbling "
Copy code
- Click on inner, Print the results :
"outer_ Capture "
"middle_ Capture "
"inner_ Capture "
"inner_ Bubbling "
"middle_ Bubbling "
"outer_ Bubbling "
Copy code
Conclusion :
- Same as the first one , First, capture events from outside to inside , All the way to the incident element , And then bubble from the inside out to the root node
Four 、 Bind bubble and capture events one by one
Let's run the fourth one first :
- Click on outer, Print the results :
"outer_ Bubbling "
"outer_ Capture "
Copy code
- Click on middle, Print the results :
"outer_ Capture "
"middle_ Bubbling "
"middle_ Capture "
"outer_ Bubbling "
Copy code
- Click on inner, Print the results :
"outer_ Capture "
"middle_ Capture "
"inner_ Bubbling "
"inner_ Capture "
"middle_ Bubbling "
"outer_ Bubbling "
Copy code
Conclusion :
Same as the second one
-
In the capture phase, events are captured from outside to inside , In the bubbling phase, bubbles from the inside out to the root node
-
The target element first performs the bubble event , Then execute the capture event
summary
Event flow execution sequence
Through the above code , We can see that , About the sequence of event capture and event bubbling :
-
In the capture phase , Capture events are executed from the outside in first ;
-
When an event triggers In the goal phase when , It will be executed according to the sequence of event registration . That is to say, if there is a bubble event registered in the Department , Also registered capture events , be Follow the order of registration ;
-
In bubbling stage , Bubbling from the inside out to the root node .
other :
-
js Code can only perform one of the capture or bubble phases ( It's either catching or bubbling )
-
onclick and attachevent(ie) You can only get the bubbling stage
-
In development , We rarely use event capture , We're more concerned about the bubbling of events
-
Some events are not bubbling , such as onblur、onfocus、onmouseenter、onmouseleave
-
The bubbling of events can sometimes cause trouble , But it can be stopped , The method is :stopPropagation()
- stopPropagation() Method : Capture of termination event in propagation process 、 Target processing or bubbling phase further spread . After calling this method , The handler on this node that handles this event will be called , Events are no longer assigned to other nodes .
What a long long road! , Share with you .
reference :
- JS Prevent bubbling and cancel default Events ( Default behavior ) | Front end development blog
- JavaScript Trapping and bubbling | Front end development blog
- DOM Event phase and the sequence of event capture and event bubbling | Blog Garden - AlvinWei
Postscript :Hello friends , If you think this article is good , Remember to like or give star, Your praise star It's my motivation to write more and richer articles !GitHub Address
Document protocol
db Document library for from db use Knowledge sharing A signature - Noncommercial use - Share in the same way 4.0 The international license agreement Licensing .
be based on github.com/danygitgit Creation of works on .
Use rights other than those authorized by this license agreement can be obtained from creativecommons.org/licenses/by… To obtain .