Javascript event Bubbling Mechanism Detailed Introduction _ Basics

Source: Internet
Author: User
Tags event listener

1. The event

In the browser client application platform, the basic health is event-driven, that is, an event occurs, and then the corresponding action is made.

A browser event indicates a signal that something is happening. The description of the event is not the focus of this article, and friends who have not yet understood can access the W3school tutorial for an understanding that will help to better understand the following content.

2. Bubbling mechanism

What is bubbling?

The following picture should be understood, the bubbles start from the bottom to rise, from deep to shallow, up to the top. In the process of rising, bubbles pass through different depths of water.

Correspondingly: This bubble is the equivalent of our events here, and water is the equivalent of our entire DOM tree; events are passed from the bottom layer of the DOM tree to the root node of the DOM.

Simple Case Analysis

The following is a simple case to illustrate the bubbling principle:

Defines an HTML that has three simple DOM elements: Div1,div2, Span,div2 contains span,div1 containing div2, and they are all under the body:

<body id= "Body" >
 <div id= "Box1" class= "Box1" >
 <div id= "Box2" class= "Box2" >
  <span ID = "Span" >this is a span.</span>
 </div>
 </div>
</body>

The interface prototype is as follows:


On this basis, we implement the following functions:

A.body Add Click event Listener, when the body captures the event events, print out the time of event occurrence and the node information that triggers the event:

<script type= "Text/javascript" >
 window.onload = function () {
 document.getElementById ("Body"). AddEventListener ("click", EventHandler);
 }
 function EventHandler (event) {
 Console.log (time: +new Date (event.timestamp) + "node generating events:" + Event.target.id + current node: " +event.currenttarget.id);
 }
</script>

When we click "This is span" in turn, the following information is output after Div2,div1,body:


Analyze the results above:

Whether it is Body,body's child element Div1, or Div's child element div2, and span, when these elements are clicked click, the Click event is generated and the body is captured, and then the corresponding event handler is invoked. As bubbles in the water take up from the bottom, events are also passed on.

The schematic diagram of the event delivery is as follows:

Generally, events have some information during delivery, which is part of the event: when the event occurred + where the event occurred + the event's current processor + other information,


The complete HTML code is as follows:

<! DOCTYPE html>  

B. Termination of the event bubbling

We now want to implement this function, in the DIV1 click, pop-up "Hello, I am the outermost div." "Hello, I'm a second-tier div" when clicked on Div2, "Hello, I'm span." "。

From this we will have the following JavaScript fragment:

<script type= "Text/javascript" >
 window.onload = function () {
 document.getElementById ("Box1"). AddEventListener ("click", Function (event) {
  alert ("Hello, I'm the outermost div.") ");
 });
 document.getElementById ("Box2"). AddEventListener ("click", Function (event) {
  alert ("Hello, I'm the second level div.") ");
 });
 document.getElementById ("span"). AddEventListener ("click", Function (event) {
  alert ("Hello, I'm span.") ");
 });
 }
</script>

Expect the above code to click Span when it comes out a pop-up box "Hello, I am span." "Yes, it does pop up such a dialog box:


However, not only will this dialog box be generated, but when the click is OK, the following dialog box will pop up:


It's obviously not what we want! What we want is a little bit of information about who's showing who. Why is there such a situation? The reason for this is the bubbling of events, which, when clicked in span, bubbles up the resulting events, and the div1 of the div2 and grandparents of the parent node also receive this event, thus responding to the event and executing the response function. Now the problem is found, but how to solve it?

Method One: Let's consider an image: A bubble in the water is going up from the bottom, and you are in the water, do not want to let this bubble up, how to do? --Pierce it! Without the bubbles, nature will not go up. Similarly, for a node, if you do not want the event it is dealing with continues to bubble up, we can stop bubbling:

In the corresponding processing function, add event.stoppropagation (), terminate the broadcast distribution of the event, such events remain in this node, will not spread out. Modify the above script fragment:

<script type= "Text/javascript" >
 window.onload = function () {
 document.getElementById ("Box1"). AddEventListener ("click", Function (event) {
  alert ("Hello, I'm the outermost div.") ");
  Event.stoppropagation ();
 });
 document.getElementById ("Box2"). AddEventListener ("click", Function (event) {
  alert ("Hello, I'm the second level div.") ");
  Event.stoppropagation ();
 });
 document.getElementById ("span"). AddEventListener ("click", Function (event) {
  alert ("Hello, I'm span.") ");
  Event.stoppropagation ();
 });
</script>

After such a piece of code, click on different elements will have different prompts, there will be no pop-up multiple boxes.

Method Two: The event contains the node reference that initially triggers the event and a reference to the current processing event node, if the node handles only the events that it triggers, not the events that it generates. Event.target references the DOM node that generated this event object, and Event.currrenttarget refers to the current processing node, and we can see if the two target is equal.

A span click event, for example, produces an event object, Event.target points to a SPAN element, and when span handles this event, the event.currenttarget points to a SPAN element, and then the decision is equal and the corresponding handler function is executed. When the event is passed to the Div2, the event.currenttarget becomes div2, then the judgment is not equal, that is, the event is not produced by the DIV2 itself, it does not respond to the processing logic.

<script type= "Text/javascript" >
 window.onload = function () {
 document.getElementById ("Box1"). AddEventListener ("click", Function (event) {
  if (event.target = = Event.currenttarget)
  {
    alert ("Hello, I am the outermost div. ");
  }
 });
 document.getElementById ("Box2"). AddEventListener ("click", Function (event) {
  if (Event.target = = Event.currenttarget)
  {
  alert ("Hello, I am the second layer div.") ");
  }
 });
 document.getElementById ("span"). AddEventListener ("click", Function (event) {
  if (Event.target = = Event.currenttarget)
  {
    alert ("Hello, I'm span.") ");
  
  }
 });
 }
</script>

Comparison:

See from the event Pass: The method is to cancel event bubbling, that is, when some nodes are not bubbling, the event will not be passed, the second method is not to prevent bubbling, filtering the events to be handled, event processing will continue to pass;

Disadvantages

Method One disadvantage: In order to achieve the click of a specific element to display the corresponding information, the method requires that each element of the child elements must also terminate the event bubbling, that is, with other elements of the function of strong association, such a method will be very vulnerable. For example, if the processing function of a SPAN element does not perform a bubbling termination, the event is passed to the DIV2, which results in a DIV2 message;

Method Two disadvantages: Method two for each element has increased the event listener processing function, the event processing logic is very similar, namely has the judgment if (event.target = = Event.currenttarget), this has the very big code redundancy, now is three element fortunately, When there are 10, how about hundreds?
There is also a process function for each element, which increases the complexity of the logic and code to some extent.

Let's analyze the method two: the principle of method two is that when the element receives the event, it determines whether the event conforms to the requirement, and then does the corresponding processing, then the event continues to bubble up and pass on;
since the event is bubbling, is it possible to have a parent node handle the event uniformly, by judging where the event occurred (that is, the node that generated the event), and then making the appropriate processing? The answer is yes, by adding an event listener to the BODY element, and then by judging Event.target and then generating different behavior for different target.

Refactor the code for method two:

<script type= "Text/javascript" >
 window.onload = function () {
 document.getElementById ("Body"). AddEventListener ("click", eventperformed);
 }
 function Eventperformed (event) {
 var target = event.target;
 Switch (target.id) {case
 "span": 
  alert ("Hello, I'm span.") ");
  break;
 Case "DIV1":
  alert ("Hello, I am the second layer div.") ");
  break;
 Case "DIV2":
  alert ("Hello, I am the outermost div.") ");
  break;
 }
 }
</script>

The result would be to click on a different element, only to pop up to match the prompts, there will be no extra hints.

through the above way, we have each element has to have the processing function, all to their grandparents node body elements to complete, that is, SPAN,DIV2,DIV1 will own response logic entrusted to the body, let it to complete the corresponding logic, they do not implement the corresponding logic, this model, Is the so-called event delegation.

Here is a schematic:

About the incident agent problem, continue to explore later.

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

Related Article

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.