在JavaScript中,如果在HTML元素及其祖先上声明了事件触发器,则首先触发

In JavaScript, if an event trigger is declared on an HTML element and its ancestor, which fires first?

本文关键字:触发器 事件 声明 祖先 如果 JavaScript HTML 元素      更新时间:2023-09-26

有两个onchange触发器:一个在INPUT上,另一个来自包含INPUT的表单。

<>之前document.getElementByTagName("形式")[0].addEventListener(‘改变’,funcForm);document.getElementByTagName("输入")[0].addEventListener(‘改变’,funcInput);之前
  1. funcForm还是funcInput先着火?

  2. 这个行为是定义和一致的吗?

  3. 如果e.stopPropagation()在第一个射击触发器上发出,第二个射击吗?

应该首先触发输入的处理程序,然后如果事件冒泡,则应该在DOM层次结构中冒泡。来自DOM Events规范:

事件被分派到它的目标EventTarget,并且在那里发现的任何事件侦听器都被触发。冒泡事件将触发任何额外的事件侦听器,通过遵循EventTarget的父链向上发现
[…]
任何事件处理程序都可以选择通过调用Event接口的stopPropagation方法来阻止进一步的事件传播。如果任何EventListener调用此方法,则当前EventTarget上的所有其他EventListeners将被触发,但冒泡将在该级别停止。为了防止进一步冒泡,只需要调用一次stopPropagation

第二段适用于stopPropagation,并说如果input上的侦听器调用e.stopPropagation(),则事件不应该到达<form>。然而,<input> 上的任何剩余侦听器都将看到更改事件,stopPropagation只是阻止事件在树中冒泡,直到stopPropagation被调用的级别。

此外,更改事件会冒泡:


当控件失去输入焦点并且自获得焦点以来其值已被修改时,将发生更改事件。此事件对INPUT、SELECT和TEXTAREA有效。元素。

  • 泡沫:是的

这取决于事件处理程序是为捕获阶段还是冒泡阶段设置的。addEventListener函数有第三个参数useCapture,默认值为false。如果useCapture为true,那么祖先元素在沿着DOM树向下移动的过程中捕获事件,并首先触发其处理程序。如果useCapture为false(默认值),则事件沿着DOM树传播到事件目标,子元素首先触发其处理程序,然后事件气泡向上显示到祖先。

所以你现在的方式是:funcInput将首先触发;行为是明确和一致的;和e.stopPropagation()将阻止funcForm和任何其他事件处理程序触发。

查看http://www.quirksmode.org/js/events_order.html和https://developer.mozilla.org/en/DOM/element.addEventListener获取更多信息