【问题标题】:Add functionality to an existing event listener向现有事件侦听器添加功能
【发布时间】:2015-03-11 21:41:30
【问题描述】:

我在表单上有一组输入,用于监视交互性、验证或两者。对于这两种情况,我不确定如何在不覆盖先前分配的情况下添加第二组功能。

这是一个例子。我有一个字段应该被监视以进行实时验证,并且应该被监视以进行一些实时格式化。 (是的,我可以将它们整合到同一个函数中,但我更愿意将它们分开)。

这是验证任务:

exampleField

    // for live typing
    .keyup($.debounce(500, debouncedValidation))

    // for copy-pastes and autofills
    .change(function(){
        validateInput(formInValidation, $(this));
    });

另外,我想独立运行一些交互式功能,如下所示:

exampleField

    // for live typing
    .keyup($.debounce(500, interactWithElement($(this))))

    // for copy-pastes and autofills
    .change(function(){
        interactWithElement($(this));
    });

我使用的是相同的事件,所以后者会覆盖前者。我的直觉说,有一种优雅的方法可以在两者之间添加一个实用函数,比如addEventListenerWithoutOverride(),它会查找现有事件并将它们组合起来。那是疯了吗?所述函数的虚构输出可能类似于:

exampleField

    .keyup(
         $.debounce(
             500,
             function(){
                 debouncedValidation();
                 interactWithElement($(this));
             });
         )
    )

    .change(function(){
        validateInput(formInValidation, $(this));
        interactWithElement($(this));
    });

【问题讨论】:

  • jQuery 默认执行此操作。如果您添加一个事件处理程序,然后为同一事件添加另一个事件处理程序,两者都将运行 - 尽管无法保证执行顺序。
  • 如果你可以在同一个元素上放置多个处理程序,那会解决你的问题吗? addEventListener()
  • @RoryMcCrossan 你在开玩笑-我没有费心设置测试,因为我确信 jQuery 更直接地开箱即用。谢谢!
  • 您也可以使用代理作为您的处理程序,然后告诉您的代理要执行什么以及按什么顺序执行

标签: javascript jquery events combinations jquery-events


【解决方案1】:

只使用on 代替吗?您可以注册任意数量的侦听器,无需担心覆盖。

$('#bind-example').on('click', function(){alert('First click!'); });
$('#bind-example').on('click', function(){alert('Second click!'); });
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<a id="bind-example" href="#">Click Me!</a>

如果我误解了您的问题,请告诉我。

【讨论】:

  • 这里没有特别的理由使用.bind()。它没有提供比.on().click() 更多的功能。事实上,如果你查看 jQuery 源代码,.bind() 所做的只是将其参数传递给.on()。而且,在 jQuery 文档中有这样的评论:“从 jQuery 1.7 开始,.on() 方法是将事件处理程序附加到文档的首选方法。”。
  • @jfriend00 是的,你当然是对的。我责怪感冒药。更新
  • 嗯,你有它。谢谢!
  • 用纯javascript怎么办?
【解决方案2】:

引用 OP 的问题:

我使用的是相同的事件,所以后者会覆盖前者。

其实不然。根据jQuery's .bind documentation

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


所以,让我们不理会文档并测试它是否真的覆盖了前一个事件:

var overriden = true;
$("button").click(function() {
    overriden = false;
});
$("button").click(function() {
    alert("Overriden? " + overriden);
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.1/jquery.min.js"></script>
<button>Test overriden events.</button>

【讨论】:

  • 这里很好地解释了这个概念 - 谢谢你的工作!
猜你喜欢
  • 1970-01-01
  • 2010-11-26
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2023-03-09
  • 2021-08-27
  • 2020-06-29
  • 2015-11-01
相关资源
最近更新 更多