JavaScript event bindings, event bubbling, event capture, and event execution Sequence collation Summary _ basics

Source: Internet
Author: User
Tags anonymous

Time to learn the next JavaScript and jquery event design, the harvest is quite large, summed up this paste, and you share.

(i) Several ways of event binding

There are 2 ways in which JavaScript binds event handlers to the DOM: Binding in HTML documents and binding in JS code. The following way 1, mode 2 belongs to binding events in HTML, Mode 3, Mode 4, and mode 5 belong to binding events in JS code, where method 5 is the most recommended practice.

Mode 1:

The HTML DOM element supports onclick, onblur, and so on with the on Start attribute, and we can write JavaScript code directly in these attribute values. When you click on the div, the following code pops up the div's ID:

<div id= "Outesta" onclick= var id = this.id;alert (ID); ></div>

This is obviously not good, because the code is placed in a string, can not be formatted and typesetting, when the code is very difficult to understand. Here's one thing to note: This in the OnClick property represents the currently clicked Dom object, so we can get the id attribute value of the DOM element through This.id.

Mode 2:

When the code is more, we can specify the function name in attributes such as onclick.

<script>

 function Buttonhandler (thisdom)
 {
 alert (this.id);//undefined
 alert (thisdom.id); /outesta return
 false;
 }
</script>
<div id= "Outesta" onclick= "Return to Buttonhandler (this);" ></div>

This is a little better than the above approach. It is worth mentioning that this is the Window object in the event handler function, so we pass the DOM object as a parameter in the OnClick property value through this.

Mode 3: In the JS code through the DOM element onclick and other attributes

var dom = document.getElementById ("Outesta");
Dom.onclick = function () {alert ("1=" + this.id);
Dom.onclick = function () {alert ("2=" + this.id);

This procedure represents the current DOM object. One more thing: This approach can only bind an event handler, and the latter will cover the front.

Method 4:ie Use the Attachevent/detachevent function for event binding and cancellation.

Attachevent/detachevent compatibility is not good, IE6~IE11 supports this function, but both FF and Chrome browsers do not support this method. And attachevent/detachevent is not a standard practice for the consortium, so it is not recommended. In IE browser, attachevent has the following characteristics.

A in the event handler function this represents a Window object, not a DOM object.

var dom = document.getElementById ("Outesta"); 
Dom.attachevent (' onclick ', a); 
   
function A () 
{  
  alert (this.id);//undefined 
}

b The same event handler function can only be bound once.

var dom = document.getElementById ("Outesta"); 
Dom.attachevent (' onclick ', a); 
Dom.attachevent (' onclick ', a);  
function A () 
{ 
  alert (this.id);
}

Although 2 times are bound using attachevent, function A is called only once.

c) different function objects, which can be repeatedly bound and not overwritten.

var dom = document.getElementById ("Outesta"); 
Dom.attachevent (' onclick ', function () {alert (1);}); 

Anonymous functions and anonymous functions are different from each other, even if the code is exactly the same. So if we want to cancel the Attachevent bound event handler with DetachEvent, then the anonymous function cannot be used when binding events, and the event function must be written as a separate function, otherwise it cannot be canceled.

Mode 5: AddEventListener and RemoveEventListener using the standard of the consortium.

These 2 functions are required by the IE6/IE7/IE8, and both FF and Chrome browsers support these 2 functions. However, the 2 standard APIs have been supported since IE9.

Type: Event types, excluding "on", such as "click", "MouseOver", "KeyDown";
and the Attachevent event name, including "on", such as "onclick", "onmouseover", "onkeydown";
Listener: Event handling function
//Usecapture is event bubbling, or event capture, default false, representing event bubbling type
AddEventListener (type, listener, usecapture) ; 

A in the event handler function this represents a DOM object, not window, which differs from attachevent.

var dom = document.getElementById ("Outesta"); 
Dom.addeventlistener (' Click ', A, false); 
   
function A () 
{  
  alert (this.id);//outesta 
}

b The same event handler function can be bound 2 times, once for event capture, and once for event bubbling.

var dom = document.getElementById ("Outesta"); 
Dom.addeventlistener (' Click ', A, false); 
Dom.addeventlistener (' Click ', A, true); 
   
function A () 
{  
  alert (this.id);//outesta 
}//Call 2 times when you click Outesta

If the same event handler is bound, and is both an event bubbling type or an event capture type, it can only be bound once.

var dom = document.getElementById ("Outesta"); 
Dom.addeventlistener (' Click ', A, false); 
Dom.addeventlistener (' Click ', A, false); 
   
function A () 
{  
  alert (this.id);//outesta 
}

//When clicked Outesta, functions a will only call 1 times

c The different event handler functions can be repeatedly bound, which is consistent with the attachevent.

(ii) Sequence of execution of event-handling functions

Mode 1, Mode 2, and mode 3 do not implement the repetitive binding of events, so there is no question of execution order in nature. Mode 4 and Mode 5 can repeat the binding attribute, so you need to understand the problem of the order of execution. If you write code that relies on the order of execution, you can conclude that your design is problematic. So the following sequence of questions, only as an interest to explore, has no practical significance. Direct conclusion:AddEventListener and attachevent behave consistently, and if you bind multiple handlers to the same event, the first binding is executed first. The following code I have tested in IE11, FF17, and Chrome39.

<script>
 window.onload = function () {
 <span style= "White-space:pre" > </span>var outa = document.getElementById ("Outa"); 
 Outa.addeventlistener (' click ', function () {alert (1);},false);
 Outa.addeventlistener (' click ', function () {alert (2);},true);
 Outa.addeventlistener (' click ', function () {alert (3);},true);
 Outa.addeventlistener (' click ', function () {alert (4);},true);
</script>

<body>
 <div id= "Outa style=" width:400px; height:400px: #CDC9C9; position:relative; " >
 </div>
</body>

When you click Outa, you will print out 1, 2, 3, 4 in turn. In particular, we need to note that we have multiple onclick event handlers for Outa, as well as events triggered by clicking Outa, so there is no problem with event bubbling and event capture, that is, the third parameter of AddEventListener is not useful in this scenario. If the Click event that triggers the Outa is triggered by event bubbling or event capture, then the order of execution of the function changes.

(iii) event bubbling and event capture

Event bubbling and event capture are very well understood, but they are a different view of the same thing, except that these 2 views make sense.
We know that elements in HTML can be nested to form hierarchical relationships similar to trees. For example, the following code:

<div id= "Outa" style= "width:400px; height:400px; Background: #CDC9C9;p osition:relative; >
 <div id= "Outb" style= "height:200; background: #0000ff; top:100px;position:relative;" >
 <div id= "OUTC" style= "height:100px; background: #FFB90F; top:50px;position:relative;" ></div> 
 </div>
</div>

If you click on the innermost OUTC, then the outer OUTB and OUTC count is clicked? Obviously, otherwise there is no need to distinguish between event bubbling and event capture, which is not a matter for the browser manufacturers. If Outa, OUTB, OUTC all registered click Type Event handler function, when click OUTC, the trigger order is a-->b-->c, or c-->b-->a? If the browser uses event bubbling, the triggering sequence is c-->b-->a, from the inside out, like bubbles, floating from the bottom to the water, and if event capture is used, then the triggering sequence is a-->b-->c, from top to bottom, like a rock, from the water to the bottom.

Event bubbles See the following figure:


Event capture See the following figure:

Generally speaking, the event bubbling mechanism is used more, so in IE8 and before, IE only supports event bubbling. Ie9+/ff/chrome These 2 models are supported and can be set by the usecapture of AddEventListener (type, listener, usecapture), Usecapture=false represent event bubbling, Usecapture=true represents the adoption of event capture.

<script>

 window.onload = function () {
 var outa = document.getElementById ("Outa"); 
 var Outb = document.getElementById ("Outb"); 
 var OUTC = document.getElementById ("OUTC"); 
 
 Use event bubbling
 outa.addeventlistener (' click ', function () {alert (1);},false);
 Outb.addeventlistener (' click ', function () {alert (2);},false);
 Outc.addeventlistener (' click ', function () {alert (3);},false);
 
</script>

<body>
 <div id= "Outa style=" width:400px; height:400px: #CDC9C9; position:relative; " >
 <div id= "Outb" style= "height:200; background: #0000ff; top:100px;position:relative;" >
  <div id= "OUTC" style= "height:100px; background: #FFB90F; top:50px;position:relative;" ></div> 
 </div>
 </div>
</body>

The use of event bubbling, when clicked OUTC, the print order is 3-->2-->1. If you change false to True using event capture, the print order is 1-->2-->3.

(iv) DOM event flow

Dom Event Stream I do not know how to explain, personal feeling is the combination of event bubbling and event capture, directly look at the picture.

Dom Event flow: Divides events into three phases: capture phase, target phase, bubbling phase. The processing function of the capture phase is called first, then the handler function of the target phase is called, and finally the processing function of the bubbling phase is called. This process is similar to the action and interceptor in the Struts2 box. When a URL request is issued, the front interceptor is called first, then the action is invoked, and the rear interceptor is invoked.

 <script> window.onload = function () {var outa = document.getElementById ("Outa"); 
 var Outb = document.getElementById ("Outb"); 
 
 var OUTC = document.getElementById ("OUTC");
 
 Whether the target (itself triggers the event, is bubbling or capturing indifferent) Outc.addeventlistener (' click ', function () {alert ("target");},true);
 Event bubbling Outa.addeventlistener (' click ', function () {alert ("Bubble1");},false);
 
 Outb.addeventlistener (' click ', function () {alert ("Bubble2");},false);
 Event Capture Outa.addeventlistener (' click ', function () {alert ("Capture1");},true); 
 Outb.addeventlistener (' click ', function () {alert ("Capture2");},true);
 
}; </script> <body> <div id= "Outa" style= "width:400px; height:400px; Background: #CDC9C9;p osition:relative; > <div id= "Outb" style= "height:200; Background: #0000ff; top:100px;position:relative; " > <div id= "OUTC" style= "height:100px; Background: #FFB90F; top:50px;position:relative; " ></div> </div> </div> </body> 

When you click OUTC, print out the capture1-->capture2-->target-->bubble2-->bubble1 in turn. Is it possible to understand the meaning of the third parameter Usecapture in the AddEventListener (type,handler,usecapture) API? Usecapture=false means that the event handlers are added to the bubbling phase and are invoked during the bubbling phase, and usecapture=true means that the event handler function is added to the capture phase and is invoked during the capture phase. As can be seen from the DOM event flow model, the event-handling functions in the capture phase must be performed first, rather than the bubbling phase's event handler.

(v) Further discussion on the sequence of execution of event functions

Mentioned in the DOM event stream:

Target (trigger event itself, bubble or catch doesn't matter)
outc.addeventlistener (' click ', function () {alert ("target");},true);

We trigger the OnClick event on the OUTC (this is the target object), what happens if we bind the capture phase/bubble phase event handler on the OUTC?

<script> window.onload = function () {var outa = document.getElementById ("Outa"); 
 var Outb = document.getElementById ("Outb"); 
 
 var OUTC = document.getElementById ("OUTC");
 Whether the target (itself triggers the event, is bubbling or capturing indifferent) Outc.addeventlistener (' click ', function () {alert ("Target2");},true);
 
 Outc.addeventlistener (' click ', function () {alert ("Target1");},true);
 Event bubbling Outa.addeventlistener (' click ', function () {alert ("Bubble1");},false);
 
 Outb.addeventlistener (' click ', function () {alert ("Bubble2");},false);
 Event Capture Outa.addeventlistener (' click ', function () {alert ("Capture1");},true);

 
 
 Outb.addeventlistener (' click ', function () {alert ("Capture2");},true);
 
}; </script> <body> <div id= "Outa" style= "width:400px; height:400px; Background: #CDC9C9;p osition:relative; > <div id= "Outb" style= "height:200; Background: #0000ff; top:100px;position:relative; " > <div id= "OUTC" style= "height:100px; Background: #FFB90F; top:50px;position:relative; " ></div> </div> </Div> </body>

 

When you click Outc, the Print order is: Capture1-->capture2-->target2-->target1-->bubble2-->bubble1. Because OUTC is the target object of our triggering event, the event handlers registered on the OUTC are part of the target phase in the DOM event stream. The order in which the target stage functions are executed: first to be registered, executed first, and then executed after registration. That's what we're talking about here, and it doesn't matter whether the function bound on the target is captured or bubbling, because bubbling and capturing only affects the order of function execution on the parent element and has no effect on itself. If you do not believe, you can put the following code in the validation.

Whether the target (itself triggers the event, is bubbling or capturing indifferent)
Outc.addeventlistener (' click ', function () {alert ("Target1");},false);
Outc.addeventlistener (' click ', function () {alert ("Target2");},true);
Outc.addeventlistener (' click ', function () {alert ("Target3");},true);
Outc.addeventlistener (' click ', function () {alert ("Target4");},false);

So far we can give the conclusion of the sequence of event functions: The processing function of the capture phase is first executed, followed by the processing function of the target phase, and finally the processing function of the bubbling phase. The target phase of the processing function, first registration of the first execution, after the registration after execution.

(vi) Blocking event bubbling and capturing

By default, multiple event-handling functions are executed in the order in which they are in the DOM event flow model. If an event occurs on a child element and does not need to perform an event handler that is registered on the parent element, then we can stop capturing and bubbling to avoid meaningless function calls. The 5 types of event bindings mentioned earlier can be used to prevent the propagation of events. Because of the 5th way, is the most recommended practice. So let's look at how to block the propagation of events based on the 5th way. IE8 and the continued propagation of events previously prevented by Window.event.cancelbubble=true, and ie9+/ff/chrome through Event.stoppropagation () to prevent the continuation of the propagation of events.

 <script> window.onload = function () {var outa = document.getElementById ("Outa"); 
 var Outb = document.getElementById ("Outb"); 
 
 var OUTC = document.getElementById ("OUTC");
  Target Outc.addeventlistener (' click ', Function (event) {alert ("target");
 Event.stoppropagation ();

 },false);

 Event bubbling Outa.addeventlistener (' click ', function () {alert ("bubble");},false); 
 
 Event Capture Outa.addeventlistener (' click ', function () {alert ("capture");},true);
 
}; </script> <body> <div id= "Outa" style= "width:400px; height:400px; Background: #CDC9C9;p osition:relative; > <div id= "Outb" style= "height:200; Background: #0000ff; top:100px;position:relative; " > <div id= "OUTC" style= "height:100px; Background: #FFB90F; top:50px;position:relative; " ></div> </div> </div> </body> 

When clicked Outc, then print out the Capture-->target, will not print out the bubble. Because when an event propagates to a processing function on OUTC, the continuation of the event is prevented by Stoppropagation, so it is not propagated to the bubbling phase.

Finally, let's look at a more interesting piece of code:

<script>

 window.onload = function () {
 var outa = document.getElementById ("Outa"); 
 var Outb = document.getElementById ("Outb"); 
 var OUTC = document.getElementById ("OUTC"); 
 
 Target
 outc.addeventlistener (' click ', Function (event) {alert ("target");},false);

 Event bubbling
 outa.addeventlistener (' click ', function () {alert ("bubble");},false);

 Event capture
 outa.addeventlistener (' click ', function () {alert (' Capture '); Event.stoppropagation ();},true); 
 
 };
 
</script>

<body>
 <div id= "Outa style=" width:400px; height:400px: #CDC9C9; position:relative; " >
 <div id= "Outb" style= "height:200; background: #0000ff; top:100px;position:relative;" >
  <div id= "OUTC" style= "height:100px; background: #FFB90F; top:50px;position:relative;" ></div> 
 </div>
 </div>
</body>



The result is that only capture are printed and target and bubble are not printed. Magically, we clicked on the OUTC, but did not trigger the event handler on the OUTC, but instead triggered the event handler on the Outa. Why do not explain, if you do not understand, you can read this article again.

Thank you for reading, I hope to help you, thank you for your support for this site!

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.