[Original translation] a vivid and detailed explanation of javascript's bubbling and capturing.

Source: Internet
Author: User

Although proficient in jquery, I am not very familiar with its prototype javascript. Recently I have encountered some difficulties in learning javascript, such as bubbling and capturing, which have been mentioned many times, but I do not know where the application is. I have found some good articles to explain and share them with you here.

Quirksmode has a series of articles that are both good and easy to understand. This article is just one of a series and has the opportunity to translate the javascript series to everyone.

Http://www.quirksmode.org/js/events_order.html. It indicates that I am not very familiar with this sentence and may be wrong. Official start:

Event occurrence Sequence

The origin of this problem is very simple. Suppose you have nested another element in one element.

-----------------------------------| element1                        ||   -------------------------     ||   |element2               |     ||   -------------------------     ||                                 |-----------------------------------

: And both have an onClick event handler ). If you click element 2, the click events of element 1 and element 2 are triggered. But which event is triggered first? Which event processing function will be executed first? In other words, what is the order of events?

 

Two Models

As expected, Netscape and Microsoft have two completely different solutions in the days of the "browser war:

  • Netscape claims that the event of element 1 first occurs. The event occurrence sequence is calledCapture type
  • Microsoft maintains that element 2 has priority. This event order is calledBubble Type

The order of the two events is the opposite. Explorer supports only bubble events. Mozilla, Opera7, and Konqueror support both events. The older opera and iCab do not support either.

 

Captured events

When you use a capture event

               | |---------------| |-----------------| element1     | |                ||   -----------| |-----------     ||   |element2  \ /          |     ||   -------------------------     ||        Event CAPTURING          |-----------------------------------

: The event handler function of element 1 is first triggered, and the event handler function of element 2 is finally triggered.

Bubble events

When you use a bubble event

               / \---------------| |-----------------| element1     | |                ||   -----------| |-----------     ||   |element2  | |          |     ||   -------------------------     ||        Event BUBBLING           |-----------------------------------

: The processing function of element 2 is first triggered, and element 1 is second

W3CModel

W3c wisely chose a right choice in this battle. Any event that occurs in the w3c event model first enters the capture stage until the target element is reached and then enters the bubble stage.

                 | |  / \-----------------| |--| |-----------------| element1       | |  | |                ||   -------------| |--| |-----------     ||   |element2    \ /  | |          |     ||   --------------------------------     ||        W3C event model                 |------------------------------------------

For a web developer, you can choose whether to bind an event handler in the capture or bubble phase. This is implemented through the addEventListener () method. If the last parameter of this function is true, bind the function in the capture phase. Otherwise, bind the function in the bubble phase.

Suppose you want

element1.addEventListener('click',doSomething2,true)

element2.addEventListener('click',doSomething,false)

If you click element 2, the following occurs:

(The event is like a visitor visiting from the outside to the inside, gradually approaching the trigger's main element, and then leaves in reverse direction)

  1. Click the event to start the capture phase (gradually approaching element 2 ). Check whether any of the ancestor elements of element 2 have The onclick processing function in the capture phase.
  2. One element 1 is found, so doSomething2 is executed.
  3. When the event is checked to the target (element 2), no more processing functions are found in the capture phase. The event starts to enter the bubble stage. take it for granted that doSomething () is executed. This function is bound to element 2 in the bubble stage.
  4. The event moves away from element 2 to check whether any ancestor element is bound with a handler in the bubble stage. There is no such situation, so nothing has happened.

The opposite is:

element1.addEventListener('click',doSomething2,false)

element2.addEventListener('click',doSomething,false)

Now, if you click element 2, the following occurs:

  1. Click events to enter the capture phase. Check whether there is an onclick processing function in the capture phase in the ancestor element of element 2.
  2. Check the event to the target. The event starts to enter the bubble stage and executes the function bound to element 2 in the bubble stage. DoSomething ()
  3. The event begins to stay away from the target and checks whether any of the ancestor elements of element 2 are bound to the handler
  4. The doSomething2 () of element 1 is executed.

Compatibility and traditional mode

In browsers that support w3c dom (Document Object Model), the traditional event binding method is

element1.onclick = doSomething2;

It is considered to be bound to the bubble stage by default.

 

Use a bubble event

Few developers will consciously use bubble events or capture events. On the webpage they created today, there is no need to let an event be processed by several functions due to bubbling. But sometimes users are often confused, because there are many situations after they only click the mouse once (multiple functions are executed because of bubbling ). In most cases, you still want your processing functions to be independent of each other. When a user clicks an element, what happens, and clicks another element, what happens is independent of each other, not because of the bubble chain.

 

Always happening

First, you need to understand that event capture or bubbling is always happening. If you define a general onclick handler for the entire page document

Document. onclick = doSomething;

If (document. captureEvents) document. captureEvents (Event. CLICK );

// I do not know what the second sentence means. For Beginners, I hope someone can explain it.

Clicking the click event of any element on the page will eventually bubble to the highest document layer on the page, so trigger that generic processing function unless the previous processing function explicitly terminates the bubble, in this way, bubbles will not be transmitted to the entire document layer.

 

Usage (the translation in this section is not good, because there is no actual practice, and I don't understand it very well. I can add it in the message and I will update it)

Because any event is propagated to the page document (the highest level), this makes the default event handler Function Possible. Suppose you have such a page

------------------------------------| document                         ||   ---------------  ------------  ||   | element1    |  | element2 |  ||   ---------------  ------------  ||                                  |------------------------------------
element1.onclick = doSomething;
element2.onclick = doSomething;
document.onclick = defaultFunction;

 

If you click element 1 or element 2, doSomething () is executed. If you do not want to let the event bubble to execute defaultFunction (), you can prevent event bubbles from spreading upwards here ,. However, if you click another part on the page, defaultFunction () will still be executed. This effect may be useful sometimes.

 

Set page -- make the processing function have a large trigger area, which is required in the "drag effect" script. In general, a mousedown event on an element layer means that this element is selected and can be used to respond to the mousemove event. Although mousedown is usually bound to this element layer to avoid browser bugs, the range of the event functions of the other two must be the whole page (?)

 

Remember that the First Law of Browserology learned by the browser is: Everything is possible (anything can happen), and at least you have a bit of preparation. So it may happen that when a user moves his or her mouse on the page, the script cannot respond in large ways, so that the mouse does not stop on the element layer.

  • If the onmouseover processing function is bound to the element layer, this element layer will no longer respond to mouse movement, which makes users feel strange.
  • If the onmouseup processing function is bound to the element layer, the event cannot be triggered. As a result, the element layer continues to respond to mouse movement after the user wants to put down the element layer. This will lead to more confusion (?)

In this example, event bubbling is very useful because placing your processing functions on the page layer ensures that they are always executed.

 

Turn it off

But in general, you will want to turn off all the bubbles and captures to ensure that the functions do not disturb each other. In addition, if your document structure is quite complex (many tables are nested with each other or so), you will also close the bubble to save system resources. In this case, the browser has to check every ancestor of the target element to see if it has a processing function. Even if none of them are found, the search just took a lot of time.

 

In Microsoft models, you must set the event cancelBubble attribute to true.

window.event.cancelBubble = true

In the w3c model, you must call the stopPropagation () method of the event.

e.stopPropagation()

This prevents all bubbles from spreading outward. As a cross-browser solution, we should do this:

function doSomething(e)

{
     if (!e) var e = window.event;

e.cancelBubble = true;

if (e.stopPropagation) e.stopPropagation();

}

Set cancelBubble in a browser that supports the cancelBubble attribute. The browser shrugged and then created this attribute. Of course, this cannot really cancel the bubble, but it can at least ensure that this command is safe and correct.

 

CurrentTarget

As we have seen before, an event uses the target or srcElement attribute to indicate the target element on which the event actually occurred (that is, the element that the user initially clicked ). In our example, element 2 is used because we click it.

It is very important to understand that the target element in the capture or bubble stage remains unchanged and is always associated with element 2.

But suppose we have bound the following functions:

element1.onclick = doSomething;

element2.onclick = doSomething;

If you click element 2, doSomething () is executed twice. But how do you know which html element is responding to this event? Target/srcElement does not give clues, but people tend to prefer element 2 because it is the cause of the event (because the user clicks on it ).

To solve this problem, w3c adds the currentTarget attribute, which points to the Element Processing the event: this is exactly what we need. Unfortunately, the Microsoft model does not have similar attributes.

You can also use the "this" keyword. In the above example, it is equivalent to the html element that is processing the event, just like currentTarget.

 

Microsoft model Problems

However, when you bind a model to a Microsoft Event, the this keyword is not equivalent to an HTML element. Lenovo lacks a Microsoft model (?) similar to the currentTarget attribute (?) -- If you follow the above Code, doing so means:

element1.attachEvent('onclick',doSomething)

element2.attachEvent('onclick',doSomething)

You cannot know exactly which HTML element is responsible for processing the event. This is the most serious problem for the Microsoft Event binding model. For me, this is why I never use it, even if you are developing an application that is only for Windows IE

 

I want to add attributes similar to currentTarget as soon as possible-or follow the standard? Web developers need this information

Postscript:

Because javascript has never been used in practice, I am not very familiar with this article. I can only translate it, for example, the section about the drag-and-drop effect, if you have any questions, please leave me a message. Thank you for your support!

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.