Home  >  Article  >  Web Front-end  >  In-depth analysis of native JavaScript events_Basic knowledge

In-depth analysis of native JavaScript events_Basic knowledge

WBOY
WBOYOriginal
2016-05-16 16:23:411064browse

JQuery, a Write Less Do More framework, will inevitably become overly knowledgeable about native js if used too much.

Xiao Cai actually didn’t want to write this blog. It seemed very basic, but when I saw that the binding and unbinding of native js events couldn’t be explained on the Internet, I decided to do some popular science.

First of all, let me state that I don’t know much about Xiaocai, I just want to share my thoughts with you.

DOM0 event model

The event model is constantly evolving, and the early event model is called DOM0 level.

DOM0 event model, supported by all browsers.

Register the event name directly on the dom object, which is how it is written in DOM0, for example:

Copy code The code is as follows:

document.getElementById("test").onclick = function(e){};

It means registering an onclick event. Of course, it has the same meaning as this way of writing:

Copy code The code is as follows:

document.getElementById("test")["onmousemove"] = function(e){};

This is nothing, they are just two ways to access js object attributes. The [] form is mainly to solve the problem that the attribute name is not a legal identifier. For example: object.123 will definitely report an error, but object["123"] will This problem is avoided. At the same time, the writing method of [] also makes js come alive. It uses strings to represent attribute names and can dynamically bind events at runtime.

Closer to home, when an event is triggered, a parameter e will be passed in by default, representing the event object. Through e, we can obtain a lot of useful information, such as the coordinates of the click, the specific DOM element that triggered the event, etc.

Only one event based on DOM0 can be registered for the same DOM node. The same event registered later will overwrite the previously registered event. For example:

Copy code The code is as follows:

var btn = document.getElementById("test");
btn.onmousemove = function(e){
alert("ok");
};
btn["onmousemove"] = function(e){
alert("ok1");
};

The result will be ok1.

Next let’s talk about this. When an event is triggered, this refers to the DOM object on which the event was triggered. For example:

Copy code The code is as follows:

var btn = document.getElementById("test");
btn.onmousemove = function(e){
alert(this.id);
};

The result is output test. Because the event is registered on the DOM node with the ID of 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:

Copy code The code 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 should overwrite the previous one. The last registered event is set to null, which unbinds the event.

Things are not over yet, the DOM0 event model also involves events written directly in HTML. For example:

Copy code The code is as follows:


Events registered in this way also follow the coverage principle. 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 dynamically calling the function (a bit like eval), so the event object will not be passed in. At the same time, this points to the window, not the DOM object that triggered the event.

DOM2 event model

Compared to DOM0, DOM2 event model only understands the following two points:

DOM2 supports the same DOM element to register multiple events of the same type.

· DOM2 adds the concepts of capturing and bubbling.

DOM2 events are managed through addEventListener and removeEventListener. Of course, this is the standard.

But browsers of IE8 and below have amused themselves and created the corresponding attachEvent and detachEvent. Due to the lack of knowledge, this article will not discuss them.

AddEventListener is of course a registered event. It has three parameters, namely: "event name", "event callback", "capture/bubble". For example:

Copy code The code is as follows:

var btn = document.getElementById("test");
btn.addEventListener("click", function(e){
alert("ok");
}, false);

Needless to say more about the event name. Compared with DOM0, the on in front is just removed.

Event callbacks are also easy to understand. I have to notify you when an event is triggered! During the callback, just like DOM0, an event parameter will be passed in by default, and this refers to the dom node that triggered the event.

The last parameter is a Boolean type, true represents a capture event, and false represents a bubbling event. In fact, it’s easy to understand. Here’s a schematic diagram:

It means that when an element triggers an event, the first thing to be notified is the window, then the document, and so on, until the element that actually triggers the event (the target element), this process is capture. Next, the event will start bubbling from the target element, and then out in sequence until it reaches the window object. This process is bubbling.

Why is it designed like this? This seems to be due to the deep historical origin. Xiaocai doesn't know much about it, so I won't talk nonsense.

It can be seen that the capture event is triggered before the bubbling event.

Suppose there is such an html structure:

Copy code The code is as follows:




Then we register two click events on the outer div, namely the capture event and the bubbling event. The code is as follows:

Copy code The code is as follows:

var btn = document.getElementById("test");
//Capture event
btn.addEventListener("click", function(e){
alert("ok1");
}, true);
//Bubble event
btn.addEventListener("click", function(e){
alert("ok");
}, false);

Finally, click on the inner div, ok1 will pop up first, and then ok will pop up. Combined with the schematic diagram above, the outer div is equivalent to the body in the figure, and the inner div is equivalent to the bottom div in the figure, which proves that the capture event is executed first, and then the bubbling event is executed.

Why should we emphasize clicking on the inner div? Because the DOM element that actually triggers the event must be inner, the outer DOM element has the opportunity to simulate capture events and bubbling events, as can be seen from the schematic diagram.

What if capturing events and bubbling events are registered on the DOM element that actually triggers the event?

The html structure is the same as above, and the js code is as follows:

Copy code The code is as follows:

var btnInner = document.getElementById("testInner");
//Bubble event
btnInner.addEventListener("click", function(e){
alert("ok");
}, false);
//Capture event
btnInner.addEventListener("click", function(e){
alert("ok1");
}, true);

Of course, click on the inner div, and the result is that ok pops up first, and then ok1 pops up. Theoretically, the capture event should be triggered first, that is, ok1 should pop up first, but this is special because we register the event on the dom element that actually triggers the event, which is equivalent to registering on the div in the picture. As can be seen from the picture, the real The DOM element that triggers the event is the end point of the captured event and the starting point of the bubbling event, so there is no distinction between events here. Whichever one is registered first will be 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 type. For example, if 3 bubbling events are registered at once, the order of execution will be based on the order of registration, first registered first and executed first. For example:

Copy code The code 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);

Of course the result is that ok, ok1, and ok2 pop up in sequence.

In order to further understand the event model, there is another scenario. If the outer div and the inner div register capture events at the same time, then when the inner div is clicked, the event of the outer div must be triggered first. The code is as follows:

Copy code The code 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 bubbling events, when the inner div is clicked, the inner div event must be executed first. The principle is the same.

Careful readers will find that when divs are nested, if you click on the inner div, the outer div will also trigger an event, which seems to be a problem!

What is clicked is obviously the inner div, but the event of the outer div is also triggered. This is indeed a problem.

In fact, when an event is triggered, an event object will be passed in by default. As mentioned before, there is a method on this event object: stopPropagation. Through this method, bubbling can be prevented, so that the outer div will not receive the event. . The code is as follows:

Copy code The code 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 bubbling
e.stopPropagation();
alert("ok");
}, false);

Finally let’s talk about how to resolve the incident. Remove event syntax: btn.removeEventListener("Event Name", "Event Callback", "Capture/Bubble");

This is the same as the parameters of the binding event. Please explain in detail:

· The name of the event refers to which event is to be resolved.

               · Event callback is a function, and this function must be the same as the function that registers the event.

· Event type, Boolean value, this must be consistent with the type when registering the event.

In other words, the name, callback, and type all work together to determine which event to release, and all are indispensable. For example:

Copy code The code is as follows:

var btn = document.getElementById("test");
//Store the callback in a variable
var fn = function(e){
alert("ok");
};
//Bind
btn.addEventListener("click", fn, false);
//Release
btn.removeEventListener("click", fn, false);

If you want the registered event to be released, the callback function must be saved, otherwise it cannot be released.

DOM0 and DOM2 mixed

Things are already very messy, but this is a mixed use, and it makes people unable to live. . .

Don’t be afraid, there is no problem in mixing them. The DOM0 model and the DOM2 model each follow their own rules and do not affect each other.

Generally speaking, it’s still about whichever one registers first and whichever one executes first, and the rest doesn’t matter.

Postscript

At this point, the native js events have been almost covered. Xiaocai only knows this. Readers are welcome to add other knowledge points.

In practical applications, real experts will not register so many events stupidly. Under normal circumstances, you only need to register an event once in the outermost dom element, and then find the real trigger through the capture and bubbling mechanism. The DOM element of the event, and finally the callback is called based on the information provided by the DOM element that triggered the event.

In other words, experts will manage events themselves instead of relying on the browser to manage them. This can improve efficiency and ensure compatibility. Isn’t that what JQuery does~

Okay, that’s the end of the tutorial, I hope it’s helpful to readers!

Statement:
The content of this article is voluntarily contributed by netizens, and the copyright belongs to the original author. This site does not assume corresponding legal responsibility. If you find any content suspected of plagiarism or infringement, please contact admin@php.cn