Summary: this article mainly records the js event model related knowledge, mainly explains the event bubbling event capture, and prevent bubbling, event related methods. There is also the difference between mouse events caused by event bubbling
Js event model development history
Original event model (DOM0-level event model)
Compatible with all browsers, there is no event flow concept. Deal with the incident immediately. The feature is that there is no way to bind multiple events to the same node, and the later events will overwrite the previous events. The stage of the event is still the bubbling stage.
- Implementation 1: Bind events directly to dom elements such as onclick=””
- Dom. Onclick =function
Standard Event Model (DOM2 level event Model)
The standard event Model is a standard event model developed by W3C and supported by modern browsers (except IE6 ~ 8). The model divides events into three phases: In the standard event model (DOM2-level events), when an event occurs on a node, the event handler for the target element is fired, and each ancestor node of the target has the opportunity to process that event.
-
Capture phase: When an event is emitted, the event is propagated from the Window object up to the target element. By default, no event listener is emitted during this process.
-
Target phase: After the event is propagated to the target element, the listener function for that event is executed on the target element. If not, it is not executed.
-
Bubbling phase: The event is propagated layer by layer from the target element, executing if there is a listener for the event along the way.
All events have a capture phase, but only some events have a bubbling phase. For more details: www.w3.org/TR/DOM-Leve…
The event binding method corresponding to the standard event model
Element. addEventListener(event, function, useCapture) useCapture: - true - Event handlers are executed during the capture phase (that is, handlers are called during the event capture phase) - false- Default. Event handlers execute in the bubbling phase (that is, call event handlers in the bubbling phase of the event)Copy the code
Prevent events from bubbling:
- Event.stoppropagation ()
$("#div1").mousedown(function(e){
var e=event||window.event;
event.stopPropagation();
});
Copy the code
- Event. target==event.currentTarget, so that the element that triggers the event is equal to the element that binds the event, can also prevent the event from bubbling;
<! DOCTYPEhtml>
<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>Document</title>
</head>
<body>
<div id="btn1">
btn1
<div id="btn2">
btn2
<div id="btn3">btn3</div>
</div>
</div>
</body>
<script>
var btn1 = document.getElementById("btn1");
var btn2 = document.getElementById("btn2");
var btn3 = document.getElementById("btn3");
btn1.onclick = function() {
if(event.target == event.currentTarget){
console.log(1)
}
}
btn2.onclick = function() {
if(event.target == event.currentTarget){
console.log(2)
}
}
btn3.onclick = function() {
if(event.target == event.currentTarget){
console.log(3)}}</script>
</html>
<style>
#btn1.#btn2.#btn3 {
width: 500px;
height: 300px;
background-color: blue;
}
#btn2 {
width: 300px;
background-color: brown;
}
#btn3 {
width: 200px;
background-color: aquamarine;
}
</style>
Copy the code
Blocking default events
Or event. The preventDefault ()return false
Copy the code
IE Event Model
IE’s event mechanism has no capture phase, and the event flow is non-standard, with only target and bubbling phases.
<button id="btn"Let me < / button > ><script type="text/javascript">
var target = document.getElementById("btn");
target.attachEvent('onclick'.function(){
alert("I am the button");
alert(this) // window
});
</script>
Copy the code
There is also a corresponding event removal function: detachEvent()
E = window.event; e.cancelBubble = true;
Prevent default events from happening: e = window.event; e.returnValue =false;
Differences between the IE model and the standard event model
- Since IE does not support event capture, there are only two parameters in the registration function, type and handler;
- In the standard event model, when registering functions, the event type is not preceded by on. In IE, on is added.
- AttachEvent registers functions as global calls. This refers to the window object.
// This refers to the current btn1
btn1.addEventListener('click'.function(){console.log(this)})
Copy the code
- Both the standard event model and IE event model allow multiple handlers to be registered for the same element for the same event type. However, in the standard event model, if the same function is registered, any function with the same name will be ignored. In IE, the same function can be registered more than once, i.e. the number of times it occurs is equal to the number of registrations.
Concepts arising from the event model
Event bubbling and event capture were developed by Microsoft and Netscape respectively to solve the problem of event flow (the order in which events occur) in a page.
The event bubbling
Microsoft has come up with a stream of events called Event Bubbling.
Event bubbling can be likened to dropping a stone into water and bubbles will continue to rise from the bottom to the surface. That is, events will start at the innermost element and propagate up to the Document object.
Event capture
Netscape proposes another stream of events called Event capturing. In contrast to event bubbling, events occur from the outermost layer up to the most concrete element.
The event agent
Delegate events bound to the child element to the parent element and let the parent element do the listening.
// Click on the parent element and listen for the parent element event. If the current clicked element contains the tag passed to the child element, the event is triggered to execute the related function.
The type of node binding event needs to be handled by the agent's element event
function bindEvent(elem, type, selector, fn) {
if(! fn) { fn = selector; selector =null;
}
elem.addEventListener(type, e= > {
const target = e.target; // The element currently clicked
if (selector) {
// Does the current click element contain the element tag that needs to be brokered
// Proxy binding
if(target.matches(selector)) { fn.call(target, e); }}else {
// Trigger yourselffn.call(target, e); }}); }Copy the code
The timing of the event broker
For event agents, there is no obvious advantage in event capture or event bubbling, but since the event bubbling event flow model is compatible with all major browsers, it is recommended to use the event bubbling event model from the perspective of compatibility
Mouseover/MouseEnter mouseleave/mouseout
- Mouseenter /mouseover mouseenter event
- Mouseleave /mouseout Mouse away event
- Mouseover Mouseleave bubbles and events are triggered when child elements are entered or left
- Mouseenter Mouseleave fires only events on the current element
The following example helps to understand the principle
<! 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>Document</title> </head> <body> <div class="inline"> <div class="box out" onmouseout="out()"> <span>out</span> </div> <div class="box leave" onmouseleave="leave()"> <span>leave</span> </div> </div> <div class="inline"> <div class="box over" onmouseover="over()"> <span>over</span> </div> <div class="box enter" Onmouseenter =" Enter ()"> <span> Enter </span> </div> </div> </body> </ HTML > <script> // mouseover event function over() { Console. log(' Triggered the mouseover event! '); } // mouseEnter function Enter () {console.log(' Triggered mouseenter! '); } // mouseout function out() {console.log(' Triggered mouseout! '); } // mouseleave function leave() {console.log(' mouseleave is triggered! '); } </script> <! Mounseenter fires only on event-bound elements. Mouseover also fires on child elements. <style>. Box {width: 200px; height: 200px; margin-bottom: 10px; background-color: aquamarine; } .over span,.enter span, .out span, .leave span { width: 50px; height: 50px; background-color: brown; } .enter span, .leave span { background-color: blue; } .inline { display: inline-block; } </style>Copy the code