In JavaScript, if an event trigger is declared on an HTML element and its ancestor, which fires first?
There are two onchange
triggers: one on the INPUT and one from the FORM containing the INPUT.
document.getElementByTagName('form')[0].addEventListener('change',funcForm); document.getElementByTagName('input')[0].addEventListener('change',funcInput);
does
funcForm
orfuncInput
fire first?is this behavior defined and consistent?
if
e.stopPropagation()
is issued on the first firing trigger, does the second fire开发者_开发知识库?
The input's handlers should be triggered first and then the event should bubble up the DOM hierarchy if it bubbles. From the DOM Events specification:
The event is dispatched to its target EventTarget and any event listeners found there are triggered. Bubbling events will then trigger any additional event listeners found by following the EventTarget's parent chain upward
[...]
Any event handler may choose to prevent further event propagation by calling thestopPropagation
method of theEvent
interface. If anyEventListener
calls this method, all additionalEventListeners
on the currentEventTarget
will be triggered but bubbling will cease at that level. Only one call tostopPropagation
is required to prevent further bubbling.
The second paragraph applies to stopPropagation
and says that if the listener on the input
calls e.stopPropagation()
, then the event should not get up to the <form>
. However, any remaining listeners on the <input>
will see the change event, stopPropagation
just keeps the event from bubbling up the tree any further than the level at which stopPropagation
is called.
Furthermore, the change event does bubble:
change
The change event occurs when a control loses the input focus and its value has been modified since gaining focus. This event is valid for INPUT, SELECT, and TEXTAREA. element.
- Bubbles: Yes
It depends on if the event handler is set for the capturing phase or the bubbling phase. The addEventListener
function has a third parameter called useCapture
which defaults to false. If useCapture
is true, the ancestor element captures the event on its way down the DOM tree and fires its handler first. If useCapture
is false (default), the event travels down the DOM tree to the event target and the child element fires its handler first, then the event bubbles up to the ancestor.
So the way you currently have it: funcInput
will fire first; the behavior is defined and consistent; and e.stopPropagation()
will prevent funcForm
and any other event handlers from firing.
Check out http://www.quirksmode.org/js/events_order.html and https://developer.mozilla.org/en/DOM/element.addEventListener for more information.
精彩评论