【问题标题】:jQuery: more than one handler for same eventjQuery:同一事件的多个处理程序
【发布时间】:2010-12-02 06:42:50
【问题描述】:

如果我将两个事件处理程序绑定到同一个元素的同一个事件会发生什么?

例如:

var elem = $("...")
elem.click(...);
elem.click(...);

最后一个处理程序“获胜”,还是两个处理程序都运行?

【问题讨论】:

    标签: javascript jquery event-handling


    【解决方案1】:

    jquery 将执行这两个处理程序,因为它允许多个事件处理程序。 我已经创建了示例代码。你可以试试

    demo

    【讨论】:

      【解决方案2】:

      两个处理程序都会运行,jQuery 事件模型允许一个元素上有多个处理程序,因此后面的处理程序不会覆盖旧处理程序。

      The handlers will execute in the order in which they were bound.

      【讨论】:

      • 原生方式会发生什么?本地人如何知道如何删除特定的?
      • 根据 DOM Level 3(参考 HTML 5 规范),事件处理程序按照它们注册的顺序执行 -w3.org/TR/DOM-Level-3-Events/#event-phasew3.org/TR/2014/REC-html5-20141028/…。可以通过传递对已注册处理程序的引用来删除事件处理程序
      • @RussCam 如果同一个处理程序被绑定多次会发生什么让我们说jQuery('.btn').on('click',handlerClick); 在不同的地方被调用而实际上没有.off 它在任何地方?
      • 请注意,对于 jQueryUI widgetfactory 小部件,如果您将处理程序设置为选项,则情况并非如此。对于要调用的旧处理程序和新处理程序,您需要使用bind 方法。详情请见:learn.jquery.com/jquery-ui/widget-factory/…
      • @MichaelScheper 随时编辑答案并使用其他信息进行更新
      【解决方案3】:

      您应该能够使用链接来按顺序执行事件,例如:

      $('#target')
        .bind('click',function(event) {
          alert('Hello!');
        })
        .bind('click',function(event) {
          alert('Hello again!');
        })
        .bind('click',function(event) {
          alert('Hello yet again!');
        });
      

      我猜下面的代码也是这样

      $('#target')
            .click(function(event) {
              alert('Hello!');
            })
            .click(function(event) {
              alert('Hello again!');
            })
            .click(function(event) {
              alert('Hello yet again!');
            });
      

      来源:http://www.peachpit.com/articles/article.aspx?p=1371947&seqNum=3

      TFM 还说:

      当一个事件到达一个元素时,所有绑定到该事件的处理程序 元素的类型被触发。如果有多个处理程序 注册后,它们将始终按照它们的顺序执行 边界。在所有处理程序都执行后,事件继续沿 正常的事件传播路径。

      【讨论】:

      • 该代码和该文章都没有定义处理程序执行的顺序。是的,这就是事件 binding 发生的顺序,但是事件处理程序被调用的顺序仍然是官方未定义的。
      • 嗯?那么“现在当点击事件发生时,将调用第一个事件处理程序,然后是第二个,然后是第三个。”不清楚?
      • 是的,我知道官方没有定义这个,而且 PPK 已经证明事件执行是随机的,但也许 jQuery 已经修复了这个 ^^
      • 啊,错过了那句话。事实上,作者被误导了。 jQuery 没有“修复”这个问题。因为规范没有正式定义顺序,所以技术上没有什么需要修复的。
      • @CrescentFresh:抱歉这么晚才回复,我才看到这个问题,但我希望你指向link,它是jQuery的官方文档,上面清楚地写着@987654326 @
      【解决方案4】:

      jQuery 的 .bind() 按绑定顺序触发

      当一个事件到达一个元素时,所有绑定到该事件的处理程序 元素的类型被触发。如果有多个处理程序 注册后,它们将始终按照它们的顺序执行 边界。在所有处理程序都执行后,事件继续沿 正常的事件传播路径。

      来源:http://api.jquery.com/bind/

      因为jQuery的其他函数(例如.click())是.bind('click', handler)的快捷方式,我猜想它们也是按照绑定的顺序触发的。

      【讨论】:

        【解决方案5】:

        使用 2 种方法使其成功运行:Stephan202 的封装和多个事件侦听器。我有 3 个搜索选项卡,让我们在一个数组中定义它们的输入文本 ID:

        var ids = new Array("searchtab1", "searchtab2", "searchtab3");
        

        当searchtab1的内容发生变化时,我想更新searchtab2和searchtab3。这样做是为了封装:

        for (var i in ids) {
            $("#" + ids[i]).change(function() {
                for (var j in ids) {
                    if (this != ids[j]) {
                        $("#" + ids[j]).val($(this).val());
                    }
                }
            });
        }
        

        多个事件监听器:

        for (var i in ids) {
            for (var j in ids) {
                if (ids[i] != ids[j]) {
                    $("#" + ids[i]).change(function() {
                        $("#" + ids[j]).val($(this).val());
                    });
                }
            }
        }
        

        我喜欢这两种方法,但是程序员选择了封装,但是多个事件侦听器也可以工作。我们使用 Chrome 对其进行了测试。

        【讨论】:

          【解决方案6】:

          有一种解决方法可以保证一个处理程序一个接一个地发生:将第二个处理程序附加到包含元素并让事件冒泡。在附加到容器的处理程序中,您可以查看 event.target 并在您感兴趣的情况下执行一些操作。

          粗略,也许,但它绝对应该工作。

          【讨论】:

            【解决方案7】:

            假设您有两个处理程序,fg,并希望确保它们以已知且固定的顺序执行,那么只需封装它们:

            $("...").click(function(event){
              f(event);
              g(event);
            });
            

            这样(从jQuery的角度来看)只有一个处理程序,它以指定的顺序调用fg

            【讨论】:

            • +1,在函数内部封装是要走的路。甚至更好的条件逻辑可以包含在处理函数中,以控制被触发的事件。
            • 处理程序的集合,其顺序由程序确定。
            【解决方案8】:

            两个处理程序都被调用。

            您可能会想到inline event binding(例如"onclick=..."),其中一个很大的缺点是只能为一个事件设置一个处理程序。

            jQuery 符合DOM Level 2 event registration model:

            DOM 事件模型允许 多事件登记 单个 EventTarget 上的侦听器。到 实现这一点,事件监听器没有 不再存储为属性值

            【讨论】:

            • @Rich:订单官方未定义。
            猜你喜欢
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 2012-08-25
            • 1970-01-01
            • 2015-07-15
            • 1970-01-01
            • 2012-03-02
            • 1970-01-01
            相关资源
            最近更新 更多