preface
Event bubbling, event capture, event delegation, and event binding are arguably the most important aspects of JavaScript fundamentals
Company: Tencent
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.
There are three stages:
- Event capture phase
- In the target stage
- Event bubbling phase
As we know, IN the DOM model, HTML is multi-layered, and when an event is generated on an HTML element, the event is propagated in a specific order between element nodes in the DOM tree. Each node in the propagation path receives this event, which is the DOM event stream. When an event occurs, it is propagated from the inside out. Because the event stream itself has no ability to process events, functions that process events are not bound to the event source. For example, if we click a button and generate a click event, the click event will start propagating up into the code that handles the event.
Event capture: Events fire from the least precise object (the Document object) to the most precise (events can also be captured at the window level, though they must be specified by the developer).
Event target: When the target element is reached, the corresponding handler for the event of the target element is executed. If no listener function is bound, it is not executed.
Event bubbling: Events are emitted from the most specific event target to the least specific event target (the Document object). When an element receives an event, it passes the event to its parent, all the way to the Window.
Note:
- The JS code can only capture or bubble one of the phases
- Onclick and attachEvent only get the bubbling phase
- AddEventListener (type, listener[, useCapture]) the third argument, if true, calls the event handler during the event capture phase; If it is false (the default is false if you do not write), it indicates the event
Bubbling phase
Electrophoresis event handler. - In real development, we rarely use event capture (older versions of IE are not compatible) and focus more on event bubbling
- Some events are not bubbling, like
Onblur, onFocus, onMouseOver, onmouseleave
- While bubbling can sometimes cause trouble, it can also do clever things, as we’ll explain later
The event object
- Event is an event object, written inside the parentheses of our listener function, as a parameter
- The event object only has the event, it is automatically created by the system for us, we do not need to pass parameters
- An event object is a collection of data related to our events, such as mouse clicks that contain information related to the mouse
- The event object can be named by ourselves, such as Event, EVT, e, etc
- Event objects also have compatibility issues. IE 6, 7, and 8 are implemented through window.event
Compatibility writing:
event = event || windoe.event;
Copy the code
Event object common properties and methods
Event object property method | instructions |
---|---|
e.target |
Returns the object that triggered the eventstandard |
e.scrElement | Return triggered events for objects that are not standard IE 6, 7, 8 use |
e.type | Return the type of the event, such as click, mouseover, and so on, without on |
e.cancelBubble | This property prevents bubbling, non-standard, IE 6, 7, 8 use |
e.returnValue | This property prevents default events (default behavior) from being non-standard, as IE 6, 7, 8 use, such as not allowing links to jump |
e.preventDefaule() |
This method prevents default event (default behavior) standards, such as not allowing links to jump |
e.stopPropagation() |
Prevent bubbling, standard |
The difference between e.target and this
This returns the object (element) to which the event is bound
E.target returns the clicked object, that is, who triggered the event, such as click event -> who was clicked
var ul = document.querySelector('ul');
ul.addEventListener('click'.function (e) {
console.log(this);
console.log(e.target);
})
//
...
// <li>123</li>
Copy the code
Prevent object default behavior (heavy)
Three ways:
e.preventDefaule();
Is a method suitable for ordinary browsers- e.returnValue; Is a property for IE 6, 7, and 8
- return false; There is no compatibility problem, but note that the following statement is not executed, directly jump out
Prevent bubbling (heavy)
event.stopPropagation(); // Normal browsers stop bubbling
- event.cancelBubble; // IE 6 7 8 stops bubbling
var father = document.querySelector('.father');
var son = document.querySelector('.son');
father.addEventListener('click', alertName, false);
son.addEventListener('click', alertName, false);
document.addEventListener('click'.function () {
alert('document');
}, false);
function alertName (event) {
alert(this.getAttribute("class"));
event.stopPropagation(); // Stop bubbling
event.cancelBubble; // IE 6 7 8 stops bubbling
}
Copy the code
Event delegate (proxy, delegate)
Principle of Event Delegation (heavy)
The idea behind event delegation is that instead of setting event listeners on each child node, you set event listeners on its parent node and then set each child node using the bubbling principle.
For example, register a click event for UL, use the target of the event object to find the current hit li, and then the event bubbles to UL. Ul has a registration event, which triggers the event listener.
The role of event delegation
The DOM is manipulated only once, improving the performance of the program.
Why event delegate? (heavy)
In JavaScript, the number of event handlers added to the page is directly related to the overall performance of the page, because the dom is constantly manipulated, the more likely the browser is to redraw and reflow, and the longer the page interaction events are, which is why dom manipulation is minimized. Each event handler is an object, so one more event handler will take up more space in memory. If you want to use the event delegate, will put all the operations in the JS program, only to its parent (if there is only one parent) this object operation, and dom operation only need to interact once, so that can greatly reduce the number of interactions with DOM, improve performance;
Small case of event delegation
Requirement: When the mouse is placed over li, the background color of li turns gray
<ul>
<li>111</li>
<li>222</li>
<li>333</li>
<li>444</li>
</ul>
Copy the code
Common implementation
Bind an event to each li to make it gray:
$("li").on("mouseover".function(){$(this).css("background-color"."gray").siblings().css("background-color"."white");
})
Copy the code
This common implementation seems fine, but if we dynamically add a new LI to ul after this code is over, the new LI will have no event, and our DOM will be overwhelmed if there are countless Li nodes.
Implementation using event delegate
Js events are bubbling, so this can change, but event.target does not. It is always the target DOM element that receives the event directly
Using event bubbling, you can control all li events under UL by specifying only UL event handling
$("ul").on("mouseover".function(e) {
$(e.target).css("background-color"."gray").siblings().css("background-color"."white");
})
Copy the code
-
Step 1: Bind events to the parent element
Add a binding event to the ul element, bind the mouseover event to the CSS (you can also add a binding for click via addEventListener)
-
Step 2: Listen for bubbling events on child elements
The default is bubbles, so if you click on the child li, it bubbles up
-
Step 3: Find which child element is the event
The event object is received with the parameter E of the anonymous callback function, and the target that triggered the event is obtained with target (the type of target can be determined by determining what kind of child object executes the event).