The DOM event flow
The event flow describes the order in which events are received from the page.
When events occur, they are propagated in a specific order between element nodes, which is called the DOM event stream.
The DOM event flow is divided into three phases:
1. Capture phase
2. Current goal stage
3. Bubble stage
For example, if we register a click event for a div, the DOM event flow diagram looks like this:
①->④ is the capture stage, ④ is the current target stage, ④->⑦ is the bubble stage.
Event capture
Under the concept of event capture, the order in which click events occur should be:
Document -> HTML -> Body -> target element
Event capture Example
<div class="outer">
<div class="inner"></div>
</div>
Copy the code
The CSS code is omitted here. The green box is the class=”outer” box, and the orange box is the class=”inner” box.
var outer = document.querySelector('.outer');
var inner = document.querySelector('.inner');
// If the third argument is true, the event handler is called during the event capture phase. The default value is false
outer.addEventListener('click'.function(){
console.log('I'm the outer of the capture phase.');
},true);
inner.addEventListener('click'.function(){
console.log('I am the inner of the capture stage');
},true);
document.addEventListener('click'.function(){
console.log('I'm the document of the capture phase');
},true);
Copy the code
Click on the orange area, i.e. click on the Inner box, and the console outputs:
Obviously, regardless of the order in which these events are registered, the event execution starts at the top level of the document. Right
The event bubbling
Event bubbling, which was first proposed by Microsoft, is a process, as opposed to event capture, that is received by the most concrete element and then passed up to the topmost node of the DOM. It can be likened to the process of bubbles rising from the bottom of the water when a stone falls into the water. This is the event bubbling stage.
Under the concept of event bubbling, the order in which click events occur should be:
Target element -> body -> HTML -> document
Example of event bubbling
<div class="outer">
<div class="inner"></div>
</div>
Copy the code
var outer = document.querySelector('.outer');
var inner = document.querySelector('.inner');
// If the third argument is false, the event handler is called during the event bubble phase. The default value is false
outer.addEventListener('click'.function(){
console.log('I'm outer in the bubble phase.');
},false);
inner.addEventListener('click'.function(){
console.log('I'm a bubbling inner');
},false);
document.addEventListener('click'.function(){
console.log('I'm a document in the bubbling phase.');
},false);
Copy the code
Once again, click on the orange area, that is, click on the inner box, and the console outputs:
Event bubbling conflicts with event capture
In general, events that do not indicate whether they are bubbling or capturing events are handled by default.
The third argument to the event listener, element.addeventListener (event, function, useCapture), is optional and defaults to false.
If an event has both capture and bubbling, it is common to call the events of the event capture phase first and then the events of the event bubbling phase
For example
var outer = document.querySelector('.outer');
var inner = document.querySelector('.inner');
outer.addEventListener('click'.function () {
console.log('I'm the outer of the capture phase.');
}, true);
inner.addEventListener('click'.function () {
console.log('I am the inner of the capture stage');
}, true);
inner.addEventListener('click'.function () {
console.log('I'm a bubbling inner');
}, false);
outer.addEventListener('click'.function () {
console.log('I'm outer in the bubble phase.');
}, false);
Copy the code
Again, click on the orange area inner and the console output will be:
The order of execution is from the outside to the inside, and then from the inside to the outside
However, when the target event is caught and bubbled, the order in which the event is executed depends on the order in which the event was registered!
Suppose we change the above code to
var outer = document.querySelector('.outer');
var inner = document.querySelector('.inner');
outer.addEventListener('click'.function () {
console.log('I'm outer in the bubble phase.');
}, false);
inner.addEventListener('click'.function () {
console.log('I'm a bubbling inner');
}, false);
inner.addEventListener('click'.function () {
console.log('I am the inner of the capture stage');
}, true);
outer.addEventListener('click'.function () {
console.log('I'm the outer of the capture phase.');
}, true);
Copy the code
The result of this run is:
Since the inner orange box is clicked, inner is the target stage, and the execution order of the target stage is determined by the registration order of the events. Since the code above registers the bubble of inner and then the capture of inner, the order of execution is to output the bubbling inner and then the captured inner.
This registration order only affects the target phase and does not affect non-target phase events. The outer box, however, is captured before bubbling.
Prevents events from bubbling
Standard: Use the stopPropagation() method in event objects
event.stopPropagation();
Non-standard: IE 6-8 uses the event object cancelBubble property
window.event.cancelBubble = true;
The stopPropagation() method is incompatible
Compatibility solution to prevent event bubbling
var outer = document.querySelector('.outer');
var inner = document.querySelector('.inner');
outer.addEventListener('click'.function () {
console.log('I'm outer in the bubble phase.');
}, false);
inner.addEventListener('click'.function (e) {
console.log('I'm a bubbling inner');
if(e && e.stopPropagation){
e.stopPropagation();
}else{
window.event.cancelBubble = true; }},false);
Copy the code
Output: I am the bubbling inner
Since the prevent event bubble is declared in inner, it will only prevent the event bubble if the target phase is in inner, but if the target phase is in outer, clicking on the green area will still bubble up.
Some events do not bubble, such as onblur, onfocus, onMouseEnter, onmouseleave, etc., can be used according to the actual development, not too much explanation here.