开发者

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);
  1. does funcForm or funcInput fire first?

  2. is this behavior defined and consistent?

  3. 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 the stopPropagation method of the Event interface. If any EventListener calls this method, all additional EventListeners on the current EventTarget will be triggered but bubbling will cease at that level. Only one call to stopPropagation 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.

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜