JQuery, a Write Less Do More framework, will inevitably look up to native js when used too much.
Xiaocai actually doesn't want to write this blog. It seems very elementary, but seeing that the binding and lifting of native js events on the network can't be understood, he decided to popularize science.
First of all, I don't know much about small dishes. I just share my ideas with you.
DOM0 event model
The event model is constantly evolving, and the early event model is called DOM0 level.
DOM0 event model is supported by all browsers.
Register the event name directly on the DOM object, which is the DOM0 writing method, for example:
1 document.getElementById("test").onclick = function(e){};
onclick means registering an event. Of course, it has the same meaning as this way of writing:
1 document.getElementById("test")["onmousemove"] = function(e){};
It's nothing. It's just two methods to access js object attributes. The form of [] is mainly to solve that the attribute name is not a legal identifier, such as object 123 certainly reports an error, but object["123"] avoids this problem. At the same time, the writing method of [] also makes js live. The attribute name is represented by a string, which can dynamically bind events at runtime.
To get back to business, when an event is triggered, a parameter E will be passed in by default to represent the event object. Through e, we can get a lot of useful information, such as the coordinates of the click, the dom element that triggers the event, and so on.
For DOM0 based events, only one can be registered for the same DOM node, and the same events registered later will overwrite the previously registered events. For example:
1 var btn = document.getElementById("test"); 2 3 btn.onmousemove = function(e){ 4 alert("ok"); 5 }; 6 7 btn["onmousemove"] = function(e){ 8 alert("ok1"); 9 };
The result is output ok1.
Let's talk about this next. When an event is triggered, this refers to the dom object on which the event is triggered. For example:
1 var btn = document.getElementById("test"); 2 3 btn.onmousemove = function(e){ 4 alert(this.id); 5 };
The result is output as test. Because the event is registered on the dom node with id test, when the event is triggered, this of course represents the dom node. It can be understood that the event is called by the 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:
1 var btn = document.getElementById("test"); 2 3 btn.onclick = function(e){ 4 alert("ok"); 5 }; 6 7 btn.onclick = null;
The principle is that the last registered event should overwrite the previous one. If the last registered event is set to null, the event binding will be released.
It's not over yet. The DOM0 event model also involves events written directly in html. For example:
1 <div id="test" class="test" onclick="exec();" ></div>
Events registered in this way also follow the coverage principle. Similarly, only one event can be registered and the last one takes effect.
The difference is that the event registered in this way is equivalent to calling the function dynamically (a bit of eval), so the event object will not be passed in. At the same time, this points to the window and is no longer the dom object that triggers the event.
DOM2 event model
Compared with DOM0, DOM2 event model only understands the following two points:
· DOM2 supports the registration of multiple events of the same kind with the same DOM element.
· DOM2 adds the concept of capture and bubbling.
DOM2 events are managed through addEventListener and removeEventListener, which is standard, of course.
However, IE8 and its following browsers entertain themselves and come up with the corresponding attachEvent and detachEvent. Due to the lack of talent and learning, this paper will not discuss them.
Of course, addEventListener is to register events. It has three parameters: event name, event callback and capture / bubble. for instance:
1 var btn = document.getElementById("test"); 2 3 btn.addEventListener("click", function(e){ 4 alert("ok"); 5 }, false);
Needless to say, compared with DOM0, the previous on is removed.
Event callback is also well understood. You must be notified when the event is triggered! During callback, like DOM0, an event parameter will be passed in by default, and this refers to the DOM node that triggers the event.
The last parameter is Boolean. true represents capture event and false represents bubble event. Actually, it's easy to understand. Let's start with a schematic diagram:
That is to say, when an element triggers an event, the first one to be notified is window, then document, and then enter successively until the element (target element) that actually triggers the event. This process is capture. Next, the events will bubble from the target element and then out in turn until the window object. This process is bubble.
Why design like this? This seems to be due to the deep historical origin. I don't know much about the dishes, so I don't talk nonsense.
It can be seen that the capture event is triggered before the bubble event.
Suppose there is such an html structure:
1 <div id="test" class="test"> 2 <div id="testInner" class="test-inner"></div> 3 </div>
Then we register two click events on the outer div, which are capture event and bubble event. The code is as follows:
1 var btn = document.getElementById("test"); 2 3 //Capture events 4 btn.addEventListener("click", function(e){ 5 alert("ok1"); 6 }, true); 7 8 //Bubbling event 9 btn.addEventListener("click", function(e){ 10 alert("ok"); 11 }, false);
Finally, click the div in the inner layer to pop up ok1 first and then 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 lowest div in the figure. It is proved that the capture event is executed first, and then the bubble event is executed.
Why should we emphasize clicking on the div in the inner layer? Because the dom element that really triggers the event must be the inner layer, and the outer dom element has the opportunity to simulate capture events and bubble events, as can be seen from the schematic diagram.
What if you register capture events and bubble events on the dom element that actually triggers the event?
The html structure is the same as above, and the js code is as follows:
1 var btnInner = document.getElementById("testInner"); 2 3 //Bubbling event 4 btnInner.addEventListener("click", function(e){ 5 alert("ok"); 6 }, false); 7 8 //Capture events 9 btnInner.addEventListener("click", function(e){ 10 alert("ok1"); 11 }, true);
Of course, click the inner div, and the result is ok first and then ok1. Theoretically, we should trigger the capture event first, that is, pop up ok1 first, but it is special here, because we register the 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 really triggers the event is the end of the capture event and the starting point of the bubbling event. Therefore, we don't distinguish the event here. Whichever is registered first is executed first. In this example, the bubbling event is registered first, so it is executed first.
This principle applies to multiple events of the same kind. For example, if three bubbling events are registered at one time, the execution order will be in the order of registration. Register first and execute first. For example:
1 var btnInner = document.getElementById("testInner"); 2 3 btnInner.addEventListener("click", function(e){ 4 alert("ok"); 5 }, false); 6 7 btnInner.addEventListener("click", function(e){ 8 alert("ok1"); 9 }, false); 10 11 btnInner.addEventListener("click", function(e){ 12 alert("ok2"); 13 }, false);
Of course, the result is to pop up OK, ok1 and ok2 in turn.
In order to further understand the event model, there is another scenario. If the capture event is registered for the outer div and the inner div at the same time, when clicking the inner div, the event of the outer div must be triggered first. The code is as follows:
1 var btn = document.getElementById("test"); 2 var btnInner = document.getElementById("testInner"); 3 4 btnInner.addEventListener("click", function(e){ 5 alert("ok"); 6 }, true); 7 8 btn.addEventListener("click", function(e){ 9 alert("ok1"); 10 }, true);
The result is to pop ok1 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. The principle is the same.
Careful readers will find that for div nesting, if you click the inner div, the outer div will also trigger an event, which seems to be a problem!
The click is obviously the inner div, but the event of the outer div is also triggered, which is really a problem.
In fact, when an event is triggered, an event object will be passed in 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 cannot receive the event. The code is as follows:
1 var btn = document.getElementById("test"); 2 var btnInner = document.getElementById("testInner"); 3 4 btn.addEventListener("click", function(e){ 5 alert("ok1"); 6 }, false); 7 8 btnInner.addEventListener("click", function(e){ 9 //Stop bubbling 10 e.stopPropagation(); 11 alert("ok"); 12 }, false);
Finally, it's time to talk about how to solve the incident. Release event syntax: BTN "Callback / removelistener", "event capture", "event name";
This is the same as the parameters of the binding event. The details are as follows:
· event name, that is, which event to cancel.
· event callback is a function, which must be the same as the function that registers the event.
· event type, Boolean value, which must be consistent with the type when registering the event.
That is to say, the name, callback and type are indispensable for deciding which event to cancel. for instance:
1 var btn = document.getElementById("test"); 2 //Store callback in variable 3 var fn = function(e){ 4 alert("ok"); 5 }; 6 //binding 7 btn.addEventListener("click", fn, false); 8 9 //relieve 10 btn.removeEventListener("click", fn, false);
If you want the registered event to be released, you must save the callback function, otherwise it cannot be released.
DOM0 mixed with DOM2
Things are already in a mess. This is a mixed use, and it doesn't let people live...
Don't be afraid. There's no problem with mixed use. DOM0 model and DOM2 model follow their own rules and don't affect each other.
On the whole, it is still the first to register and the first to execute, and there is nothing else.
Postscript
So far, the original js event has been almost talked about. The dishes only know these. Readers are welcome to add other knowledge points.
In practical application, real experts will not register so many events foolishly. Generally, they only need to register the event once in the outermost dom element, then find the dom element that really triggers the event through the capture and bubble mechanism, and finally call the callback according to the information provided by the dom element that triggers the event.
In other words, experts will manage events themselves without relying on the browser, which can improve efficiency and ensure compatibility. Isn't that what JQuery does~
Well, this is the end of the tutorial. I hope it will be helpful to readers!
Finally: in the process of learning the web front end, you will inevitably encounter many problems, which may perplex you for a long time. Therefore, I have a web development learning exchange group( 545667817 ), all of them are small partners of CSDN , and have sorted out the most comprehensive front-end learning materials. From the most basic HTML+CSS+JS to the actual learning materials of the mobile HTML5 project, you can apply to join if you want to learn. We learn from each other, communicate with each other, work together and share different learning materials every day!