Problem Introduction:
A DOM element binds two events, one bubbling, one capture, how many times the event executes, and the order of execution.
This time do not sell thinking, directly give you an answer. If you don't understand it, keep looking down.
the events that bind to the clicked element occur in the order of the Code, the other elements bubble up or capture the "perceived" event, and the event is followed by a bubbling event followed by the standard of the consortium. the order of all events is: Other element capture phase events-> This element code sequence event-> other element bubbling phase events. AddEventListener Parameters
Element.addeventlistener (type, function, usecapture)
//event type, event handler, optional. A Boolean value that specifies whether the event is executed during the capture or bubbling phase. True: The event handle executes in the capture phase; false: Default. The event handle executes in the bubbling phase.
1. Bubbling
Bubbling is from the bottom up, when the DOM element-bound event is triggered, when the element is the target element, and after the target element is executed, the event that its ancestor element binds is executed in ascending order.
Four nested Div, as shown in the following code:
the third parameter of the AddEventListener function is set to False to indicate that it is not a catch event, that is, a bubbling event.
<div id= ' one ' >
<div id= ' two ' >
<div id= ' three ' >
<div id= ' four ' >
</div >
</div>
</div>
</div>
<script type= ' text/javascript ' >
var one= document.getElementById (' one ');
var Two=document.getelementbyid (' two ');
var Three=document.getelementbyid (' three ');
var Four=document.getelementbyid (' four ');
One.addeventlistener (' click ', Function () {
alert (' one ');
},false);
Two.addeventlistener (' click ', Function () {
alert (' two ');
},false)
; Three.addeventlistener (' click ', Function () {
alert (' three ');
},false)
; Four.addeventlistener (' click ', Function () {
alert (' four ');
},false)
; </script>
the order in which code is executed is:
Click one element to output one;
Click two element to output two one;
Click three element to output three two one;
Click four element to output four three two one; 2. Capture
Capture is the opposite of bubbling, when a target element is triggered, it is carried down from the topmost ancestor element event of the target element to the target element.
change the third parameter of the above code to true, and the event is executed in the capture phase.
Note: Deleting a target element in an event handler can also prevent event bubbling, and the target element is the prerequisite for event bubbling in the document.
The results of the implementation are as follows:
Click one, output one;
Click Two, output one two;
Click Three to output one two three;
Click Four to output one two three four;
It is clear that the order of execution is different. 3. When an element binds two events, one bubbles, one captures
First, the element executes the capture phase first, whether it is a bubbling event or a catch event.
From the top down, if there is a catch event, execution; After the target element, the bubbling element is executed upward from the target element, that is, the third parameter is true to indicate that the capture phase invokes the event handler, and if False is the bubbling phase invoke event handler. (during an upward execution, a catch event that has already been executed is no longer executed and only a bubbling event is performed.) )
The following code:
One.addeventlistener (' click ', Function () {
alert (' one ');
},true);
Two.addeventlistener (' click ', Function () {
alert (' two ');
},false)
; Three.addeventlistener (' click ', Function () {
alert (' three ');
},true)
; Four.addeventlistener (' click ', Function () {
alert (' four ');
},false);
At this point, click the four element , the four element is the target element, one is the root element ancestor, and the execution is judged from one beginning.
Analysis:
One for capturing events, output one;
Two for bubbling events, ignoring;
Three for capture time, output three;
Four is the target element, it begins to bubble up and executes, outputting four, which is easier to understand from two parts. )
Three for capture has been performed, ignored;
Two for bubbling event, output two;
One for capture has been executed, ignored.
The final result is: one three four two
For example,three as the target element , executing the result: one three two (because two is a bubbling event that was not executed when executing down).
number of executions: several events were bound and executed several times.
The following code, the two element is bound to two different events, and clicking Two will perform both events. And the order of execution is different.
One.addeventlistener (' click ', Function () {
alert (' one ');
},true);
Two.addeventlistener (' click ', Function () {
alert (' two,bubble ');
},false)
; Two.addeventlistener (' click ', Function () {
alert (' two,capture ');
},true)
; Three.addeventlistener (' click ', Function () {
alert (' three,bubble ');
},true)
; Four.addeventlistener (' click ', Function () {
alert (' four ');
},true);
1. If the two is the target element, the same event of the target element executes sequentially, while the other elements are executed according to the standard of the consortium, which is first captured and then bubbled.
Click two execution results: one (because the parent element of the two supports capturing events so it executes first) two,bubble
Two,capture (sequential execution, note that commas are not intervals, are output.) )
2, if the target element is not two, then the two of the same type event is first captured and then bubbled to execute, which is the same as the execution of the previous discussion, except that two events are bound to the same DOM element.
Click three execution results: one two,capture three,bubble two,bubble Summary
So, when you see this, you should understand:
the events that bind to the clicked element occur in the order of the Code .
Other elements are bubbling or capturing "perceptual" events.
According to the standards of the consortium, a Catch event occurs first, followed by a bubbling event. The order of all events is: other element capture phase events-> This element code sequence event-> other element bubbling phase events . As an example
<! DOCTYPE html>
The result:
Outer
Inner
<
Changes, if here: Inner.addeventlistener (' click ', h ()); Do not cancel bubbling
Output:
Outer
Inner
the body encountered the pit one: The newly inserted child element does not have a fixed-point hit event
A UL element in the initial state has 4 Li elements, we can loop to the LI element to add click event, execute the action we want. The hole in this example is that the newly added LI element will not have the Click event that we bind.
<ul class= "Container" >
<!--first loop to the original 4 Li-bound click event-->
<li class= "item" ></li>
<li class= "Item" ></li>
<li class= "item" ></li>
<li class= "Item" ></li>
<!--This is the newly added Li element, but the element is not bound Click event-->
<li class= "Item new" ></li>
</ul>
Use event delegates:
$ (' Ul.container '). Click (Function (event) {
var target = event.target;
if (Target.classname = = ' item ') {
//dosomething
}}
)
event delegates have many benefits:
-New Li elements can also have the same event
-Bind the event to the parent element (UL), and the child element (LI) immediately has the appropriate event when it appears, without waiting for subsequent JS bindings to trigger
-Do not have to cycle through the DOM multiple times without having to have many event handlers to save memory and bind the time pit two: If the target element has child elements, then what to do.
<li class= "Item" >
<div class= "title" >xxx</title>
<p class= "desc" >xxxxxxs</p >
</li>
Solution:
<! DOCTYPE html>
Pit Three: talking about the removal of empty event handlers in JavaScript
Event-delegation techniques can be used to limit the number of connections established. In addition, removing event handlers when not needed is a solution to this problem.
Problem: Leaving unused "empty event handlers" in memory is a major cause of Web application memory and performance problems.
in both cases, an "empty event handler" may result:
The first is when you remove an element with an event handler from the document . This may be done through pure DOM operations, such as using the RemoveChild () and ReplaceChild () methods, but more often when a part of the page is replaced with innerHTML. If an element with an event handler is deleted by innerHTML, the event handlers that were added to the element will most likely not be garbage collected.
Common scene: A button is surrounded in a DIV element, to avoid double-clicking, click this button to remove and replace the button with a message.
The problem is that when the button is removed from the page, it comes with an event handler, setting the innerHTML in the <div> element to remove the button, but the event handling is still referenced by the button.
Some browsers, especially IE, do not do proper processing in this case, and they are likely to keep references to elements and event handlers in memory. If you want to know that a certain element is about to be removed, it is best to manually remove the event handler .
<div id= "mydiv" >
<input type= "button" value= "click Me" id= "mybtn" >
</div>
<script Type= "Text/javascript" >
var btn=document.getelementbyid ("Mybtn");
Btn.onclick=function () {
btn.onclick=null;
document.getElementById ("Mydiv"). Innerhtml= "Processing ...";
}
Note: Using event delegates can also solve this problem.
If you know beforehand that it is possible to replace a part of a page with innerHTML, you can also handle events in the zone by assigning the event handler to the element of the best level without directly adding the event handler to that part of the element.
The second scenario that causes an "empty event handler" is when the page is unloaded.
Not surprisingly, IE is still the most problematic browser in this case, although other browsers have more or less similar problems. If a clean event handler is not cleaned before the page is unloaded. Then they'll be stuck in memory. Each time the page is loaded and the page is unloaded (perhaps by switching between two pages or by clicking the Refresh button), the number of objects stranded in memory increases, because the memory occupied by the event handler is not freed.
Generally, the best practice is to remove all event handlers through the OnUnload event handler before the page is unloaded. Here, the event-delegation technology shows its advantages again-the fewer event programs that need to be tracked, the easier it is to remove them.
For such a similar operation, we can imagine that, as long as something is added through the OnLoad event handler, it is eventually removed by the OnUnload event handler.
Note: Do not forget that using the OnUnload event handler means that the page will not be cached in Bfcachek, and if you care about it, you can only remove the event handler through OnUnload in IE. Reference Links:
1, the Event execution order introduction: http://www.cnblogs.com/greatluoluo/p/5882508.html
2, the event entrusted: http://www.cnblogs.com/greatluoluo/p/6282509.html