[html5] Event capture/bubbling question

Berend-Jan Wever skylined at chromium.org
Thu Jan 27 03:01:32 PST 2011


Hey all,

I was experimenting with event capturing and bubbling when I noticed
something odd: "capturing" event handlers are executed for the target of an
event AFTER "bubbling" event handlers have been executed for that target.
For example, if an event is fired on a "div" inside a "body", I see the
following event listeners being fired in the same order in all mayor browser
(Chrome, FF, MSIE (9 beta), Opera, Safari):
1) "capture" event listeners for the Document element
2) "capture" event listeners for the "html" element
3) "capture" event listeners for the "body" element
4) "bubble"  event listeners for the "div" element
5) "capture" event listeners for the "div" element
6) "bubble"  event listeners for the "body" element
7) "bubble"  event listeners for the "html" element
8) "bubble"  event listeners for the Document element

This fifth entry is odd because:
1) I didn't expect to see "capturing" event listeners to get executed for
the target at all.
2) I expected all "capturing" event handlers to be executed before any
"bubbling" event listeners.

Let me explain where these expectations come from by showing how I interpret
the spec at(
http://www.w3.org/TR/DOM-Level-2-Events/events.html#Events-flow-capture):
Section 1.2.1, paragraph 1:

"Although all EventListeners<http://www.w3.org/TR/DOM-Level-2-Events/events.html#Events-EventListener>
on
the EventTarget<http://www.w3.org/TR/DOM-Level-2-Events/events.html#Events-EventTarget>
are
guaranteed to be triggered by any event which is received by that
EventTarget, no specification is made as to the order in which they will
receive the event with regards to the other
EventListeners<http://www.w3.org/TR/DOM-Level-2-Events/events.html#Events-EventListener>
on
the EventTarget<http://www.w3.org/TR/DOM-Level-2-Events/events.html#Events-EventTarget>
. *<snip>* If event capture or event bubbling is in use, the event flow will
be modified as described in the sections below.".

Section 1.2.2, paragraph 2:

"when an event of the given type is dispatched toward a *descendant* of the
capturing object, the event will trigger any capturing event listeners of
the appropriate type which exist in the direct line between the top of the
document and the event's target. This downward propagation continues until
the event's target is reached. A capturing EventListener will not be
triggered by events dispatched directly to the EventTarget upon which it is
registered."

paragraph 3:

"event capture only allows interception of events which are targeted at *
descendants* of the capturing EventTarget." and "event capture intercepts
all events of the specified type targeted toward any of the capturer's *
descendants*.")."

To me this means "capture" event listeners are *not* executed for the target
element.
Section 1.2.2, paragraph 1.2.2:

"If no additional capturers exist and stopPropagation has not been called,
the event triggers the appropriate EventListeners on the target itself."

This means "bubbling" event listeners *are* executed for the target element
*after* the last "capturing" event listener has been executed.

Here's how I interpret the spec step-by-step:
1) Create a list of all nodes from the target "upwards" through its parents
towards the Document element. This list is not modified even if elements are
removed or added while executing the next steps.

== Capturing phase ==
2) Set the current element to the "topmost" element at of the list.
3) Fire all "capture" event listeners for the current element (in any
order).
4) If "stopPropagation()" has been called go to step 12.
5) Set the current element to the next element "down" in the list.
6) If the current element is not the target element go to step 3.

== Bubbling phase ==
7) Fire all "bubbling" event listeners for the current element (in any
order).
8) If "stopPropagation()" has been called stop executing these steps.
9) If the current element is the Document element at the "top" of the list
stop executing these steps.
10) Set the current element to the next element "up" in the list.
11) Go to step 7

== Default behavior phase ==
12) if "preventDefault()" has been called, stop executing these steps
13) Execute the default browser behavior for the event and the target, such
as opening a link when clicking on it.

I've attached a test case that I used to find out about this. They way I see
it, there are a few options:
- I am interpreting the output of my test wrong,
- The test has a bug that causes it to display the event order incorrectly,
- The spec is not clear on this subject and I am interpreting it
incorrectly,
- The spec is incorrect,
- All mayor browser have implemented "capturing" incorrectly.

Let me know if you have any idea what is going on!

Cheers,

SkyLined


Berend-Jan Wever (SkyLined at google.com) | Security Software Engineer
Google Netherlands B.V. | Reg: Claude Debussylaan 34, 15th floor 1082 MD
Amsterdam
34198589 | NETHERLANDS | VAT / Tax ID:- 812788515 B01


Berend-Jan Wever (SkyLined at google.com) | Security Software Engineer
Google Netherlands B.V. | Reg: Claude Debussylaan 34, 15th floor 1082 MD
Amsterdam
34198589 | NETHERLANDS | VAT / Tax ID:- 812788515 B01
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.whatwg.org/pipermail/help-whatwg.org/attachments/20110127/5e298022/attachment.htm>
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.whatwg.org/pipermail/help-whatwg.org/attachments/20110127/5e298022/attachment.html>


More information about the Help mailing list