Detailed description of event handling in JavaScript

Source: Internet
Author: User
Tags event listener

In the long history of evolution, we have said goodbye to inline event handling (using the event handler directly within the HTML element), today's event, which is already an important part of the DOM, unfortunately, IE continues to retain its earliest implementation of the event model in the IE4.0, and later in the IE version did not make too much change, which means that IE is still using a proprietary event model (bubbling type), and other mainstream browsers until the DOM level 3 to finalize the decision, only to continue to support the DOM standard event processing model --Capture type and bubble type.

The Web-based specification does not define any events in DOM Level 1 until DOM level 2, published in November 2000, defines a small subset, and DOM Level 2 provides a more detailed and more granular way to control the events in the page, and finally, The complete event was finalized in the 2004 DOM Level 3 rule, since IE4 was introduced in 1995 and has implemented its own event model (bubbling type), there was no DOM standard at the time, but the IE event model was absorbed in the later DOM standard specification process.

First, what is an event?

JavaScript gives us the ability to create dynamic pages, events that can be detected by JavaScript, and every element in a Web page can produce certain events that can trigger JavaScript functions.

For example, we can trigger a function by generating an onclick event when the user taps a button, and the event is defined in the HTML page (see the Ma Haixiang blog, "JS Basics: JavaScript Event Trigger List" for an introduction).

Event is the heart of the JavaScript app beating, and the glue that sticks everything together, and the event happens when we interact with the Web page in the browser for some type of interaction.

An event might be a user clicking on something, a mouse passing through a specific element, or pressing some key on the keyboard, something that might happen in a Web browser, such as when a Web page is loaded, or when a user scrolls or changes the window size.

By using JavaScript, you can listen to the occurrence of a particular event and specify that certain events occur to respond to these events.

Second, DOM event flow

The DOM (Document Object model) structure is a tree structure, and when an HTML element produces an event, the event propagates in a particular order between the element node and the root node, and the node that passes through the path receives the event, which can be called the DOM event stream.

1. Type of event sequence

There are two types of event order: event snapping and event bubbling.

(1), bubbling events (event bubbling)

This is the Internet Explorer's implementation of the event model, but also the most easy to understand, at least Ma Haixiang feel more in line with the actual.

Bubbling, as the name implies, the event goes up like a bubble in the water until the top.

It is understood from the DOM tree structure that the event is passed from the leaf node up to the root node along the ancestor nodes, and the hierarchy of the HTML elements from the browser interface view is understood to be that the event is passed from the most determined target element with a dependency to the most uncertain target element. The basic idea of a bubbling event is that the event is based on the target of the most uncertain event, starting from the specific event target.

(2), capture-type events (event capturing)

The implementation of Netscape, which is just the opposite of the bubbling type, consists of the topmost element of the DOM tree up to the most precise element, and this event model is somewhat confusing to the developer (at least me), because the intuitive understanding should be like bubbling, and event delivery should start with the most deterministic element, the event-generating element.

2. DOM Standard event Model

We have explained and compared the above two different event models, and the DOM standard supports both event models, capturing and bubbling events, but capture-type events occur first, and both event streams trigger all objects in the DOM, starting with the Document object, Also at the end of the Document object (most compliant browsers continue to persist the event as snap/bubble to the Window object).

The first is the capture pass event, followed by the bubbling pass, so if a handler function registers the listener for the captured event and registers the bubbling event listener, it will be called two times in the DOM event model (see the Ma Haixiang blog, 3 ways to read the JavaScript event handler) The relevant introduction).

The most unique nature of the DOM standard event model is that text nodes also trigger events (not in IE).

3. Event Delivery

To better illustrate the principle of event flow in the DOM standard, we put it in the "event routing" summary to explain it more specifically.

Obviously, if you add a click event Listener to a hyperlink, the event listener is executed when the link is clicked.

However, if you assign the event listener to the P element that contains the link or to the document node at the top of the DOM tree, clicking the link also triggers the event listener, because the event not only affects the target element that is being triggered, but also affects all elements along the DOM structure. This is what we all know about the event forwarding.

The principle of event forwarding is clearly pointed out in the event model, and the event transmission can be divided into 3 stages:

(1), during the event capture (capturing) phase, the event will be forwarded down the DOM tree, each ancestor node of the target node, up to the target node.

For example, if a user clicks a hyperlink, the Click event is forwarded from the document node to the HTML element, the BODY element, and the P element that contains the link.

During this process, the browser detects the listener for the event's capture event and runs the event listener.

(2), at the target stage, the browser runs the event listener after it finds the event listener that has been assigned to the target event, and the target node is the DOM node that triggered the event.

For example, if a user clicks on a hyperlink, the link is the target node (the target node is actually a text node within the hyperlink).

(3), during the bubbling (bubbling) phase, the event will be forwarded upward along the DOM tree, once again accessing the ancestor node of the target element to the document node, each step in the process, the browser detects the event listeners that are not the listener of the event and executes them.

4, not all events will go through the bubbling phase

All events go through the capture and target stages, but some events skip the bubbling phase.

For example, the focus event that gives the element input focus and the Blur event that loses the input focus will not bubble.

Third, event handle and event listener

Next, Ma Haixiang the event handle and event listener in detail for you, so you can say that these 2 events play a big role in JavaScript event handling.

1. Event handle

The event handle (also known as the event handler function, which the DOM calls the event listener function), the function that is called in response to an event is called an event handler, and each event corresponds to an event handle, and when the program executes, assigns the corresponding function or statement to the event handle, when the event occurs, The browser executes the specified function or statement, which enables the interaction of the Web page content with the user's actions.

When the browser detects that an event occurs, it finds the event handle that corresponds to the event, and if so, executes the event handle.

Ma Haixiang that the function that responds to a click event is the OnClick event handler, which previously had two ways of assigning the event handler: in JavaScript or in HTML.

If you are assigning event handlers in JavaScript, you need to first obtain a reference to the object to be processed, and then assign the function to the corresponding event handler property, see a simple example:

var Link=document.getelementbyid ("MyLink");
Link.onclick=function () {
Alert ("I was clicked!");
};

From the example we see, we find it easy to use an event handle, but the event handler name must be lowercase, and the event handle can be assigned to an element only after the element is loaded, or there will be an exception.

If you assign an event handle in HTML, you can set the event handler directly through the HTML attribute, and include the appropriate script as the attribute value, for example:

<a href= "/" onclick= "JavaScript code here" >......</a>

This kind of JavaScript code is similar to assigning CSS properties directly to elements through the HTML style property, which makes the code look messy and violates the principle of separating code that implements dynamic behavior from the code that displays the static content of the document, which has been obsolete since 1998.

The advantages and disadvantages of this traditional event binding technique are obvious:

(1), simple and convenient, in the HTML directly write the processing function of the code block, in JS to the element corresponding to the event attribute assigned to the value.

(2), IE and DOM standards are supported by a method, which in the IE and DOM standards are in the event bubbling process is called.

(3), the element that registers an event can be referenced directly within the processing function block, and this refers to the current element.

(4), to register multiple listeners for the element, you cannot use this method.

2. Event Receiver

In addition to the simple event handles that have been described earlier, most browsers now have more advanced event handlers built into them, that is, event listeners, which are not constrained by the binding of an element to only one event handle.

We already know that the most significant difference between an event handle and an event listener is that you can only plug in one event handle at a time using an event handle, but for an event listener, you may be able to plug in multiple at a time.

(1), ie under the event listener

IE provides an own, completely different, and even bug-based event listener, so if you want the script to work properly in this browser, you must use the event listener supported by IE.

Also, event listeners in Safari are sometimes a little different.

In IE, each element and window object has two methods: the Attachevent method and the DetachEvent method.

Element.attachevent ("OnEvent", EventListener);

This method means that in IE, to attach an event handler function to an element's event, the Attachevent method must be called to create an event listener, and the Attachevent method allows the outside to register the element with multiple event listeners.

Attachevent accepts two parameters, the first parameter is the event type name, the second parameter eventlistener is the callback handler, and here's the point where there's a lot of error, Under IE, when using attachevent registered handler function call this point is no longer the element of the previously registered event, this is the Window object, and one point is that the event type name of this method must be prefixed with an "on" (such as onclick).

Element.attachevent ("OnEvent", EventListener);

To remove the event listeners registered by the previous element, you can use the DetachEvent method to delete the same parameters.

(2), Dom standard event listener

In browsers that support the standard event listener, you can use the AddEventListener method for each object that supports events, which supports both registered bubbling event handling and capture-type event handling, so it differs from registering element event listeners in Internet Explorer.

Standard syntax
Element.addeventlistener (' event ', EventListener, usecapture);
Default
Element.addeventlistener (' event ', EventListener, false);

The AddEventListener method accepts three parameters, the first parameter is the event type name, and it is worth noting that here the event type name differs from IE, the event type name does not start with ' on ', and the second parameter eventlistener is the callback handler function (that is, the listener function) The third parameter indicates whether the processing callback function is called during the capture phase of the event pass or the bubbling phase, usually this parameter is set to False (is bubbling when false), and if its value is set to True, then a capture event listener is created.

Removing the registered event listener calls the element's RemoveEventListener method, with the same parameters.

Standard syntax
Element.removeeventlistener (' event ', EventListener, usecapture);
Default
Element.removeeventlistener (' event ', EventListener, false);

The event handlers that are added through the AddEventListener method must be removed by using the RemoveEventListener method. It also requires that the parameters be exactly the same as the parameters of the AddEventListener method when the event handler is added (including the usecapture parameter), otherwise the event handler will not be successfully deleted.

(3) Cross-browser registration and removal of element event listener scenarios

We now know that for browsers that support the AddEventListener method, the AddEventListener method needs to be called whenever an event listener script is required, and for IE browsers that do not support this method, You need to call the Attachevent method when using event listeners.

It is not difficult to make sure that the browser is using the correct method, but only through a if-else statement to detect whether the AddEventListener method or Attachevent method is present in the current browser.

This way, you can implement a cross-browser registration and removal element Event listener scenario:

var eventutil = {
Registered
Addhandler:function (element, type, handler) {
if (Element.addeventlistener) {
Element.addeventlistener (type, handler, false);
} else if (element.attachevent) {
Element.attachevent ("On" + type, handler);
} else {
Element["on" + type] = handler;
}
},
Remove Registration
Removehandler:function (element, type, handler) {
if (Element.removeeventlistener) {
Element.removeeventlistener (type, handler, false);
} else if (element.detachevent) {
Element.detachevent ("On" + type, handler);
} else {
Element["on" + type] = NULL;
}
}
};

3. Event object reference

To better handle events, you can take different actions depending on the specific properties of the event that occurs (see the Ma Haixiang Blog, "Basic Tutorial Guide to JavaScript Object Properties" for an introduction).

As with the event model, IE and other browsers handle different ways: IE uses a global event object called event to process the object (it can be found in the global variable window.event), and all other browsers use the method of the recommended way, the independent containing the event object to pass the parameters.

When you implement such a feature across browsers, the most common problem is getting a reference to the event itself and getting a reference to the target element of the event.

The following code solves this problem for you:

var eventutil ={
Getevent:function (event) {
Return event? Event:window.event;
},
Gettarget:function (event) {
return Event.target | | Event.srcelement;
}
};

Iv. default behavior for stopping event bubbling and blocking events

The two concepts of stop event bubbling and block browser default behavior are important, and they are useful for complex application processing.

1. Stop event bubbling

Stop event bubbling refers to stopping the further passing of bubbling events (canceling event delivery, not just stopping the bubbling events common to the IE and DOM standards, but also stopping the capture-type event that supports the DOM standard browser, using the Toppropagation () method).

For example, in a bubbling event pass, the event listener for document on the upper level no longer receives notification and is no longer processed after the body handles the stop event delivery.

2. The default behavior of blocking events

The default behavior of a stop event is that the browser performs the default action associated with the event (if such an action exists) after the event is passed and processed.

For example, if the input Type property in the form is "submit", the form is automatically submitted after the click of the event after it has been propagated, or, for example, when the INPUT element's KeyDown event occurs and is processed, the browser will automatically append the characters typed by the user to the value of the INPUT element.

3, the processing method of stopping event bubbling

Under IE, by setting the cancelbubble of the event object to True.

function Somehandle () {
Window.event.cancelBubble = true;
}

The DOM standard is done by invoking the Stoppropagation () method of the event object.

function Somehandle (event) {
Event.stoppropagation ();
}

As a result, cross-browser stop events are delivered in the following ways:

function Somehandle (event) {
Event = Event | | window.event;
if (event.stoppropagation) {
Event.stoppropagation ();
}else {
Event.cancelbubble = true;
}
}

4. How to handle the default behavior of blocking events

Just like the event model and event object differences, the default behavior of blocking events in IE and all other browsers is different.

Under IE, by setting the returnvalue of the event object to False.

function Somehandle () {
Window.event.returnValue = false;
}

The DOM standard is done by invoking the Preventdefault () method of the event object.

function Somehandle (event) {
Event.preventdefault ();
}

Because of this, the default way to handle cross-browser cancellation events is:

function Somehandle (event) {
Event = Event | | window.event;
if (Event.preventdefault) {
Event.preventdefault ();
}else{
Event.returnvalue = false;
}
}

Full event-handling compatibility function:

var eventutil = {
Addhandler:function (element, type, handler) {
if (Element.addeventlistener) {
Element.addeventlistener (type, handler, false);
} else if (element.attachevent) {
Element.attachevent ("On" + type, handler);
} else {
Element["on" + type] = handler;
}
},
Removehandler:function (element, type, handler) {
if (Element.removeeventlistener) {
Element.removeeventlistener (type, handler, false);
} else if (element.detachevent) {
Element.detachevent ("On" + type, handler);
} else {
Element["on" + type] = NULL;
}
},
Getevent:function (event) {
Return event? Event:window.event;
},
Gettarget:function (event) {
return Event.target | | Event.srcelement;
},
Preventdefault:function (event) {
if (Event.preventdefault) {
Event.preventdefault ();
} else {
Event.returnvalue = false;
}
},
Stoppropagation:function (event) {
if (event.stoppropagation) {
Event.stoppropagation ();
} else {
Event.cancelbubble = true;
}
};

Five, capture-type event model and the application of bubbling event model

The standard event model gives us two scenarios where many friends may not be able to tell the difference between the two different models, and why not just take a model, where the IE browser discussion (ie only one, unable to choose) is suitable for what kind of event model.

1, capture-type applications

Capture-type event delivery is performed by the most imprecise ancestor element to the most precise event source element, and is passed in the same way as the application shortcut key in the operating system, when a system key combination occurs, if the system global shortcut listener is registered, the event is first captured by the operating system layer. The global listener is notified before the application shortcut listener, that is, the global first gain control, and it has the right to prevent further delivery of the event.

So the capture-type event model is suitable for listening in the global scope, where the global is relative to the global, relative to a top-level node and the node of all descendants of the formation of the collection range.

For example: you want to make a global click event monitoring, relative to the document node and all the sub-nodes under the document, under a certain condition requires all sub-node click Invalid, in this case the bubble model can not solve, and the capture type is very suitable for the top node to add the capture-type event listener, The pseudo code is as follows:

function Globalclicklistener (event) {
if (Caneventpass = = False) {
Canceling an event further to the child node and bubbling delivery
Event.stoppropagation ();
Default execution after canceling a browser event
Event.preventdefault ();
}
}

In this way, when the caneventpass condition is false, all of the child node click Registration Events under document will not be processed by the browser.

2, Bubble type of application

It can be said that we usually use the bubble event model, because IE only support this model, here or say, in the proper use of the model can improve the performance of the script, in the element of some frequently triggered events, such as Onmousemove,onmouseover, onmouseout, if there is no need for further delivery after the event is clear, then you can boldly cancel it.

In addition, the processing of the child node event listener can negatively affect the parent listener processing, and the event should be prevented from further upward passing in the child node listener to eliminate the impact.

Vi. Comprehensive case studies JavaScript event handling

Finally, we combine the following HTML code for analysis:

<body onclick= "alert (' Current is body ');" >
<div id= "Div0" onclick= "alert (' current is ' +this.id) ' >
<div id= "Div1" onclick= "alert (' current is ' +this.id) ' >
<div id= "Div2" onclick= "alert (' current is ' +this.id) ' >
<div id= "event_source" onclick= "alert (' current is ' +this.id) ' ></div>
</div>
</div>
</div>
</body>

After the HTML run, click on the red area, which is the innermost div, according to the above, whether it is the DOM standard or IE, directly written in the HTML of the Listener processing function is the event bubbling transfer call, from the innermost layer has been passed up, so it will appear successively:

Current is event_source
Current is Div2
Current is Div1
Current is Div0
Current is body

Add the following fragment:

var div2 = document.getElementById (' div2 ');
Eventutil.addhandler (Div2, ' click ', Function (event) {
event = Eventutil.getevent (event);
Eventutil.stoppropagation (event);
}, False);
Event_sourcecurrent is Div2

When you click on the red area, according to the above description, during bubble bubbling processing, the event is passed to Div2 after it is stopped, so the elements of the upper layer Div2 not receive the notification, so it will appear successively.

In a browser that supports DOM standards, add the following code:

Document.body.addEventListener (' click ', Function (event) {
Event.stoppropagation ();
}, True);

The listener function in the above code is called because it is a capture type, so after clicking on the red area, although the event source is an element with ID event_source, but captures the selection pass, starting at the topmost level, the Body node listener function is called first, and the event is canceled further down, So only the current is body appears.

Ma Haixiang Blog Comments:

At present, in addition to IE browser, other mainstream Firefox,opera,safari support the standard DOM event processing model, IE still use its own proprietary event model, namely bubble type, its event model is a part of the DOM standard adopted, this is also beneficial for developers, Only using the DOM standard, IE has a common event handling method to effectively cross the browser.

This article for Ma Haixiang Blog original article, if want to reprint, please indicate the original site from the http://www.mahaixiang.cn/js/1095.html, annotated source, otherwise, no reprint; Thank you!

Detailed description of event handling in JavaScript

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.