Javascript event bubbling details and capture and block methods

  • 2020-03-30 02:35:26
  • OfStack

The sequence of events

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 the user clicks on element 2, the click events for both element 1 and element 2 are triggered. But which event is triggered first? Which event handler will be executed first? In other words, what is the order of events?

Two, two models

Not surprisingly, Netscape and Microsoft had two very different approaches to the "bad old days" of the browser wars:

Capture events

When you use capture events

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

: element 1's event handler is fired first, element 2's event handler is fired last

4. Bubbling events

When you use bubbling events

---------------| |-----------------
| element1     | |                |
|   -----------| |-----------     |
|   |element2  | |          |     |
|   -------------------------     |
|        Event BUBBLING           |

: the handler of element 2 is triggered first, and element 1 second

5. W3C model

The W3c has wisely chosen an alternative to this battle. Any event that occurs in the w3c event model first enters the capture phase, until the target element is reached, and then enters the bubbling phase

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

For a web developer, you can choose whether to bind the event handler in the capture or bubbling phase through the addEventListener() method, which binds the function in the capture phase if the last parameter of the function is true, or false in the bubbling phase.

Suppose you want to do it

element1.addEventListener('click',doSomething2,true) element2.addEventListener('click',doSomething,false)

If the user clicks element 2, the following happens:

(the event is like a tourist here, traveling from the outside to the inside, getting closer to the main element being triggered, and then going the other way.)

1. Click the event first to enter the capture phase (gradually approaching the direction of element 2). See if any of the ancestor elements of element 2 have an onclick handler in the capture phase
2. Element 1 is found to have one, so doSomething2 is executed
3. The event checks to the target itself (element 2), and the capture phase finds no more handlers. Events start to bubble, so it's easy to do doSomething(), which is bound to the bubbling phase of element 2.
4. The event moves away from element 2 to see if any of the ancestor elements are bound to a handler during the bubbling phase. There was no such thing, so nothing happened
The opposite is true:

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

Now if the user clicks on element 2:

1. Click the event to enter the capture phase. Check to see if any of the ancestor elements of element 2 have an onclick handler in the capture phase, and you get nothing
2. The event checks to the target itself. The event starts to bubble and executes the function bound to the bubble phase of element 2. DoSomething (),
3. As the event starts to move away from the target, check whether any of the ancestor elements of element 2 have handlers bound during the bubble phase
4. One is found, and the doSomething2() of element 1 is executed

Vi. Compatibility and traditional modes

Use bubble events

Eight, it happens all the time

The first thing you need to understand is that event capture or bubbling happens all the time. If you define a generic onclick handler for the entire document page

document.onclick = doSomething;
if (document.captureEvents) document.captureEvents(Event.CLICK);

Clicking on any element on the page ends up bubbling up to the highest document level on the page, so that common handler is triggered, unless a previous handler explicitly says stop bubbling, so that the bubbling doesn't propagate to the entire document level

Supplement to the second sentence of the above code:

> > > Say first IE
Object.setcapture () when an object is captured by setCapture, its methods will be inherited to the entire document for capture.
Object.releasecapture () is used when you do not need to inherit methods to the entire document capture
> > > others
Mozilla has similar functionality, but in a slightly different way
Window. CaptureEvents (Event. EventType)
Window. ReleaseEvents (Event. EventType)
> > > example

//If this is the only sentence, then only the click of obj will trigger the click ;     Obj. Onclick = function () {alert (" something ")} < br / >
//Add the following sentence, and the method will be inherited into the document (or window, depending on the browser) to catch 
obj.captureEvents(; //FF
obj.setCapture()  //IE

Nine, usage,

Since any event propagation ends at the page document (this highest level), this makes the default event handler possible, assuming you have such a page

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


Now if the user clicks on element 1 or element 2, doSomething() will be executed. If you like, if you don't want the event to bubble up to defaultFunction(), you can stop the event from bubbling up here. But if the user clicks elsewhere on the page, defaultFunction() will still be executed. Such effects may sometimes work.

Settings page ­ - allows the handler to have a wide range of trigger areas, which is required in drag-and-drop scripts. Generally, a mousedown event at an element level means that the element is selected and that it responds to the mousemove event. Although mousedown is usually bound to this element layer to avoid browser bugs, the scope of the other two event functions must be the entire page (?).

Remember the First Law of Browserology: anything can happen, and when you're at least a little prepared. So what can happen is that when the user drags and drags his mouse across the page, he moves his mouse across the page by a large margin, and the script doesn't respond in the large margin, so that the mouse is no longer at the element level

1. If the onmouseover handler is bound to the element layer, the element layer will no longer react to mouse movement, which will make the user feel strange
2. If the onmouseup handler is bound to the element layer, the event cannot be triggered. As a result, the element layer continues to react to mouse movement after the user wants to drop the element layer. This will cause more confusion.

So in this case, event bubbling is very useful because placing your handlers in the page layer ensures that they are always executed

Ten, turn it off (prevent the event from bubbling)

But in general, you want to turn off all the bubbling and trapping to make sure that the functions don't disturb each other. On top of that, if your document structure is fairly complex (many tables nested within each other, and so on), you'll also shut down bubbling to save system resources. At this point the browser has to check each ancestor of the target element to see if it has a handler. Even if none were found, the search took time

In the Microsoft model, you must set the cancelBubble property of the event to true

window.event.cancelBubble = true

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

This will prevent all the bubbles from spreading outward. As a cross-browser solution, you should:

function doSomething(e) {
      if (!e) var e = window.event;          e.cancelBubble = true;          if (e.stopPropagation) e.stopPropagation(); }

Eleven, currentTarget

As we've seen before, an event USES the target or srcElement attribute to indicate which target element the event is on (the element that the user first clicked on). In our case, it's element 2, because we clicked it.

It is important to understand that the target element during the capture or bubbling phase is constant and is always associated with element 2.

But suppose we bind the following function

element1.onclick = doSomething;
element2.onclick = doSomething;

If the user clicks on element 2, doSomething() is executed twice. But how do you know which HTML element is responding to this event? The target/srcElement doesn't give a clue either, but people always prefer element 2 because it's the cause of the event (because it's the one the user clicked on).
To solve this problem, the w3c adds the currentTarget attribute, which points to the element that is processing the event: this is exactly what we need. Unfortunately, there are no similar attributes in the Microsoft model
You can also use the "this" keyword. In the above example, it corresponds to the HTML element that is processing the event, like currentTarget.

Problems with the Microsoft model

But when you use the Microsoft event binding model, this keyword is not equivalent to an HTML element. Lenovo lacks a Microsoft model (?) with properties like currentTarget. By following the code above, you are saying:


You can't know exactly which HTML element is handling the event, which is the most serious problem with the Microsoft event binding model, and for me, that's why I never use it, even when developing applications for IE under Windows only


  PS: here again for you to recommend an online query tool about JS events, summed up the common JS event types and functions:

Javascript events and function description:


Related articles: