【问题标题】:The Order of Multiple Event Listeners多个事件监听器的顺序
【发布时间】:2012-03-19 17:33:38
【问题描述】:

我在使用 Prototype 处理点击事件时遇到了一个奇怪的问题。如果单击下面代码中的按钮,它将触发三个警报:“单击 1”、“单击 2”和“单击 3”。现代浏览器将按照注册的顺序调用监听器,而 IE8(可能还有旧的 IE 版本)将以相反的顺序调用它们。我觉得这很奇怪,因为我认为 Prototype 维护并执行了一个侦听器队列,它应该是独立于浏览器的。不是这样吗?如果不是,事件侦听器是否应该按特定顺序运行,或者它们是异步的,因此它们的顺序无关紧要?

    <button id="button">Click me</button>
    <script type="text/javascript">
        $('button').observe('click', function(event) {
            alert('Click 1');
        });
        $('button').observe('click', function(event) {
            alert('Click 2');
        });
        $('button').observe('click', function(event) {
            alert('Click 3');
        });
    </script>

【问题讨论】:

    标签: javascript prototypejs dom-events


    【解决方案1】:

    Prototype 依赖于浏览器的底层触发机制(并非所有库都这样做,见下文)。最初的 DOM 事件内容并不能保证事件处理程序被触发的顺序。来自DOM2 Events specification

    尽管EventTarget 上的所有EventListeners 都保证由该EventTarget 接收到的任何事件触发,但没有指定它们将接收事件的顺序相对于另一个EventListenersEventTarget

    包括 IE9 在内的绝大多数浏览器实现(Chrome、Firefox、Opera 等)都会按照处理程序的附加顺序触发处理程序。 IE8 及更早版本则相反。

    较新的DOM3 event spec,仍在进行中,引入了按注册顺序触发它们的要求(大多数浏览器都这样做):

    接下来,实现必须确定当前目标的候选事件侦听器。这必须是按注册顺序在当前目标上注册的所有事件侦听器的列表。

    ...这可能是 IE9 现在这样做的部分原因(IE9 显着改进了 Microsoft 对事件标准的支持,添加了 addEventListener 等)。

    一些 JavaScript 库(例如 jQuery)do 通过为每个元素的每个事件仅附加一个处理程序并维护自己的要触发的用户代码处理程序列表来保证顺序而不受浏览器的影响。

    【讨论】:

      【解决方案2】:

      作为@T.J. 的格式化评论。克劳德的回答,我测试了哪些现代浏览器实际上按注册顺序触发了监听器。

      2016-10-06:结果是以下所有浏览器都这样做: chrome 53、firefox 49、safari 9、opera 40,即 11 和 edge 13,通过 mac 主机上的 virtualbox。

      我的测试代码可以在这里找到:https://github.com/lingtalfi/browsers-behaviours/blob/master/listeners-execution-order/listeners.md

      【讨论】:

        【解决方案3】:

        根据这个bug report,它似乎是一个现有的错误,它实际上是依赖于浏览器的。

        总结报告:

        它取决于浏览器,但一些用户(如海报)希望事件按顺序触发。错误条目曾一度更改为文档更改(以通知用户订单实际上未指定),但该错误仍处于打开状态,因此我假设它尚未在文档中修复。

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2011-07-05
          • 2018-06-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          相关资源
          最近更新 更多