给现有的事件监听器添加功能

3

我有一组表单输入,需要进行交互检查、验证或二者兼备。在两种情况下,我不确定如何添加第二个功能集而不覆盖之前的赋值。

这里举一个例子。我有一个字段应该被实时验证,并且也应该被实时格式化监控。(是的,我可以将它们合并到同一个函数中,但我更喜欢将它们分开)。

这里是验证分配:

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默认会这样做。如果您添加了一个事件处理程序,然后在稍后为同一事件添加另一个事件处理程序,则两者都将运行 - 尽管执行顺序不能保证。 - Rory McCrossan
如果您可以在同一元素上放置多个处理程序,那么这能解决您的问题吗?addEventListener() - Les
@RoryMcCrossan 你在开玩笑吧 - 我没设测试是因为我确定 jQuery 开箱即用更直白。谢谢! - technopeasant
你也可以将代理作为处理程序,然后告诉你的代理要执行什么以及以什么顺序执行。 - Les
2个回答

3
只需要使用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
@jfriend00 当然,你是对的。我怪感冒药。已更新。 - Madbreaks
好的,这就是它。谢谢! - technopeasant
如何才能不使用纯JavaScript完成这个任务? - Xitcod13

2

原文摘自提问者:

我正在使用相同的事件,因此后者会覆盖前者。

实际上并不是这样的。根据jQuery的.bind文档

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


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

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>


1
这里对概念进行了很好的解释 - 感谢您的工作! - technopeasant

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接