If you use the Write Less Do More framework like JQuery, you will inevitably be less likely to be good at native JS.
Xiaocai actually doesn’t want to write this blog, it seems to be very rudimentary, but seeing that she can’t even explain the binding and dismantling of native js events on the Internet, she decided to make some popular science.
First of all, Xiaocai doesn’t know much, just share my ideas with you.
DOM0 event model
Event models are constantly evolving, and the early event models are called the DOM0 level.
DOM0 event model, supported by all browsers.
Registering the event name directly on the dom object is the DOM0 writing method, such as:
The code copy is as follows:
document.getElementById("test").onclick = function(e){};
It means registering an onclick event. Of course, it has the same meaning as this writing:
The code copy is as follows:
document.getElementById("test")["onmousemove"] = function(e){};
This is nothing, it's just two ways to access js object properties. The form of [] is mainly to solve the problem that the attribute name is not a legal identifier. For example, object.123 must report an error, but object["123"] avoids this problem. At the same time, the writing of [] also writes js alive, using strings to represent the attribute name, which can dynamically bind events at runtime.
Back to the point, when the event is triggered, a parameter e will be passed by default to represent the event object. Through e, we can obtain a lot of useful information, such as the coordinates of the click, the dom element that specifically triggered the event, etc.
Based on DOM0 events, for the same dom node, only one can be registered, and the same event registered later will override the previous registered ones. For example:
The code copy is as follows:
var btn = document.getElementById("test");
btn.onmousemove = function(e){
alert("ok");
};
btn["onmousemove"] = function(e){
alert("ok1");
};
The result will output ok1.
Let’s talk about this next. When an event is triggered, this refers to which dom object the event is triggered. For example:
The code copy is as follows:
var btn = document.getElementById("test");
btn.onmousemove = function(e){
alert(this.id);
};
The result outputs test. Because the event is registered on the dom node with id test, when the event is triggered, this of course represents this dom node. It can be understood that the event is called by this dom node.
Therefore, it is quite simple to cancel the event. You only need to register the event again and set the value to null, for example:
The code copy is as follows:
var btn = document.getElementById("test");
btn.onclick = function(e){
alert("ok");
};
btn.onclick = null;
The principle is that the last registered event must overwrite the previous one. Set the last registered event to null, which will unbind the event.
The matter is not over yet, and the DOM0 event model also involves events written directly in the html. For example:
The code copy is as follows:
<div id="test" onclick="exec();" ></div>
Events registered in this way also follow the coverage principle, and only one can be registered and the last one will take effect.
The difference is that the event registered in this way is equivalent to calling a function dynamically (somewhat eval means), so the event object will not be passed in. At the same time, this points to window, and is no longer the dom object that triggers the event.
DOM2 event model
Compared with DOM0, Shouca only understands the following two points:
・ DOM2 supports the registration of multiple same events with the same dom element.
・ DOM2 has added the concept of capture and bubbling.
DOM2 events are managed by addEventListener and removeEventListener, of course, this is the standard.
However, IE8 and the following browsers have created corresponding attachEvent and detachEvent. Since Xiaocai is a little unintentional, this article will not discuss it.
addEventListener is of course the registration event. It has three parameters, namely: "event name", "event callback", and "capture/bubble". For example:
The code copy is as follows:
var btn = document.getElementById("test");
btn.addEventListener("click", function(e){
alert("ok");
}, false);
Needless to say, the event name is not too much. Compared with DOM0, the previous on is just removed.
Event callbacks are also easy to understand. You must notify you if the event is triggered! When calling back, like DOM0, an event parameter will be passed by default. At the same time, this refers to the dom node that triggers the event.
The last parameter is the boolean type, true represents the capture event, and false represents the bubble event. Actually, it's easy to understand. Let's first make a diagram:
It means that if an element triggers an event, the first thing that is notified is the window, and then the document, and goes in sequence until the element (target element) that actually triggers the event. This process is capture. Next, the event will bubble from the target element and then exit in sequence until the window object. This process is bubble.
Why design this way? This seems to be due to its profound historical origins, so Xiaocai doesn’t know much about it, so she won’t talk nonsense.
From this we can see that the capture event is triggered before the bubble event.
Suppose there is such an html structure:
The code copy is as follows:
<div id="test">
<div id="testInner"></div>
</div>
Then we register two click events on the outer div, namely the capture event and the bubbling event, the code is as follows:
The code copy is as follows:
var btn = document.getElementById("test");
//Catch events
btn.addEventListener("click", function(e){
alert("ok1");
}, true);
//Bubbling Event
btn.addEventListener("click", function(e){
alert("ok");
}, false);
Finally, click on the inner div, first pop up ok1, then pop up ok. Combined with the above schematic diagram, the outer div is equivalent to the body in the figure, and the inner div is equivalent to the bottom div in the figure, proving that the capture event is executed first, and then the bubble event is executed.
Why emphasize clicking on the inner div? Because the dom element that really triggers the event must be from the inner layer, and the outer layer dom element has the opportunity to simulate and capture events and bubble events, which can be seen from the schematic diagram.
What if you register the capture event and the bubbling event on the dom element that actually triggers the event?
The html structure is the same as above, and the js code is as follows:
The code copy is as follows:
var btnInner = document.getElementById("testInner");
//Bubbling Event
btnInner.addEventListener("click", function(e){
alert("ok");
}, false);
//Catch events
btnInner.addEventListener("click", function(e){
alert("ok1");
}, true);
Of course, click on the inner div, and the result is that ok first pops up, then ok1. In theory, the capture event should be triggered first, that is, ok1 pops up first, but here is special, because we register an event on the dom element that actually triggers the event, which is equivalent to registering on the div in the figure. From the figure, we can see that the dom element that actually triggers the event is the end point of the capture event and the starting point of the bubble event, so there is no distinction between events here. Which one registers first, executes which one first. In this example, the bubble event is registered first, so it is executed first.
This principle applies to multiple events of the same kind. For example, if 3 bubble events are registered at once, the execution order will be in the order of registration, first register and first execute. For example:
The code copy is as follows:
var btnInner = document.getElementById("testInner");
btnInner.addEventListener("click", function(e){
alert("ok");
}, false);
btnInner.addEventListener("click", function(e){
alert("ok1");
}, false);
btnInner.addEventListener("click", function(e){
alert("ok2");
}, false);
The result is of course ok, ok1, and ok2 pop-ups in turn.
In order to further understand the event model, there is another scenario. If the outer div and the inner div register the capture event at the same time, then when clicking the inner div, the outer div event must be triggered first. The code is as follows:
The code copy is as follows:
var btn = document.getElementById("test");
var btnInner = document.getElementById("testInner");
btnInner.addEventListener("click", function(e){
alert("ok");
}, true);
btn.addEventListener("click", function(e){
alert("ok1");
}, true);
The result is that ok1 pops up first.
If both the outer div and the inner div are registered bubble events, when clicking the inner div, the inner div event must be executed first, and the principle is the same.
Careful readers will find that for the case of div nesting, if you click on the inner div, the outer div will also trigger an event, which seems to be a problem!
The click is clearly the inner div, but the outer div event is also triggered, which is indeed a problem.
In fact, when the event is triggered, an event object will be passed by default. As mentioned earlier, there is a method on this event object: stopPropagation. Through this method, bubbles can be prevented, so that the outer div will not receive the event. The code is as follows:
The code copy is as follows:
var btn = document.getElementById("test");
var btnInner = document.getElementById("testInner");
btn.addEventListener("click", function(e){
alert("ok1");
}, false);
btnInner.addEventListener("click", function(e){
//Stop bubbles
e.stopPropagation();
alert("ok");
}, false);
Finally, I have to talk about how to resolve the incident. Unevent syntax: btn.removeEventListener("event name", "event callback", "capture/bubble");
This is the same as the parameters of the binding event, as described in detail:
・ The name of the event means to cancel the event.
・ Event callback is a function, which must be the same as the function that registers the event.
・ Event type, Boolean value, this must be consistent with the type when the event is registered.
In other words, name, callback, and type, together decide which event to cancel, is indispensable. For example:
The code copy is as follows:
var btn = document.getElementById("test");
//Storing the callback in a variable
var fn = function(e){
alert("ok");
};
//Binding
btn.addEventListener("click", fn, false);
//Removal
btn.removeEventListener("click", fn, false);
In order for the registered event to be cancelled, the callback function must be saved, otherwise it cannot be cancelled.
Mixed DOM0 and DOM2
Things are already very messy, and this is a mixed use, which makes people live. . .
Don't be afraid, it's no problem to use it in a mixed manner. The DOM0 model and the DOM2 model each follow their own rules and do not affect each other.
Overall, there is nothing else if it is registered first and executed first.
postscript
At this point, the native js event has been almost done. Xiaocai only knows this. Readers are welcome to add other knowledge points.
In actual applications, real experts will not stupidly register so many events. Generally speaking, you only need to register an event on the outermost dom element, and then use the capture and bubble mechanism to find the dom element that actually triggers the event, and finally call the callback based on the information provided by the dom element that triggers the event.
In other words, experts will manage events themselves without relying on browsers to manage them, which can improve efficiency and ensure compatibility. Isn’t this what JQuery does?
OK, the tutorial ends here, I hope it will be helpful to readers!