I just wanted to get the general consensus on which is a better mode of event delegation in JS between bubbling and capturing.
Now I understand that depending on a particular use-case, one might want to use capturing phase over bubbling or vice versa but I want to understand what delegation mode is preferred for most general cases and why (to me it seems bubbling mode).
Or to put it in other words, is there a reason behind W3C addEventListener
implementation to favor the bubbling mode. [capturing is initiated only when you specify the 3rd parameter and its true. However, you can forget that 3rd param and bubbling mode is kicked in]
I looked up the JQuery's bind function to get an answer to my question and it seems it doesn't even support events in capture phase (it seems to me because of IE not support capturing mode).
So looks like bubbling mode is the default choice but why?
In the past it was a platform issue, Internet Explorer had a bubbling model, and Netscape was more about capturing (yet supported both).
The W3C model calls for you be able to choose which one you want.
I think bubbling is more popular because, as stated there are some platforms that only support bubbling...and it sort of makes sense as a "default" mode.
Which one you choose is largely a product of what you are doing and what makes sense to you.
While reading JavaScript: The Definitive Guide, 5th Edition, I came across Example 17-4 on page 422 that defines a function for dragging absolutely positioned elements. In the example, the function drag()
is called in the onmousedown
attribute of a document element. The function repositions the element based on the change in location of the mouse which is queried by handlers added to the root document element for captured mousemove and mouseup events. They capture these events on the document for the following reason:
It is important to note that the mousemove and mouseup handlers are registered as capturing event handlers because the user may move the mouse faster than the document element can follow it, and some of these events occur outside the original target element.
This suggests an advantage in quicker response when capturing events.
This test suggests there is a slight performance advantage to using capture over bubble. Even without killing the event as soon as it is handled, however when left it was marginal. I suppose a complex DOM would exaggerate the performance difference between the two.
This link gives the clear explanation- https://www.quirksmode.org/js/events_order.html
You, the web developer, can choose whether to register an event handler in the capturing or in the bubbling phase. This is done through the addEventListener()
method explained on the Advanced models page. If its last argument is true the event handler is set for the capturing phase, if it is false the event handler is set for the bubbling phase.
Suppose you do
element1.addEventListener('click',doSomething2,true)
element2.addEventListener('click',doSomething,false)
If the user clicks on element2 the following happens:
The click event starts in the capturing phase. The event looks if any ancestor element of element2 has a onclick event handler for the capturing phase. The event finds one on element1. doSomething2() is executed. The event travels down to the target itself, no more event handlers for the capturing phase are found. The event moves to its bubbling phase and executes doSomething(), which is registered to element2 for the bubbling phase. The event travels upwards again and checks if any ancestor element of the target has an event handler for the bubbling phase. This is not the case, so nothing happens. The reverse would be
element1.addEventListener('click',doSomething2,false)
element2.addEventListener('click',doSomething,false)
Now if the user clicks on element2 the following happens:
The click event starts in the capturing phase. The event looks if any ancestor element of element2 has a onclick event handler for the capturing phase and doesn’t find any. The event travels down to the target itself. The event moves to its bubbling phase and executes doSomething(), which is registered to element2 for the bubbling phase. The event travels upwards again and checks if any ancestor element of the target has an event handler for the bubbling phase. The event finds one on element1. Now doSomething2() is executed. Compatibility with traditional model In the browsers that support the W3C DOM, a traditional event registration
element1.onclick = doSomething2;
is seen as a registration in the bubbling phase.
Use of event bubbling Few web developers consciously use event capturing or bubbling. In Web pages as they are made today, it is simply not necessary to let a bubbling event be handled by several different event handlers. Users might get confused by several things happening after one mouse click, and usually you want to keep your event handling scripts separated. When the user clicks on an element, something happens, when he clicks on another element, something else happens.
Of course this might change in the future, and it’s good to have models available that are forward compatible. But the main practical use of event capturing and bubbling today is the registration of default functions.
I'm not certain but I'm pretty sure that anything you can do with bubbling you can do with capturing and vice versa.
The idea that you'd have some events bubbling and some capturing in the same app sounds like a good way to make things very confusing. What I'm saying is, I don't think bubbling versus capturing really matters. What matters is that you pick one and stick with it.
W3C's APIs often contain this sort of thing where they have a lot of features that nobody really cares about. Perhaps this is another example of how good defaults can remove the need for configuration or even whole features.
精彩评论