【问题标题】:jQuery .on(); vs JavaScript .addEventListener();jQuery .on();与 JavaScript .addEventListener();
【发布时间】:2012-02-18 05:48:04
【问题描述】:

有人能解释一下为什么事件处理程序的执行顺序会根据它们的附加方式而有所不同吗?在下面的示例中,我使用.on().addEventListener() 方法来处理不同DOM 元素上的特定事件。

jsfiddlehttp://jsfiddle.net/etsS2/

我认为在这个特定示例中,事件处理程序的执行顺序将取决于 event-bubbling - 所以从原始事件 target 开始,一直到 document 元素。

document.getElementById('outer').addEventListener('mouseup', function (event) {
//$('#outer').on('mouseup', function (event) {
    alert('This alert should not show up!');
}, false);

如果我取消注释 on(); 版本,一切都会按预期工作 - jQuery 处理事件的方式与普通 JavaScript 不同吗?

【问题讨论】:

    标签: javascript jquery event-handling


    【解决方案1】:

    addEventListener版本:

    document.getElementById('outer').addEventListener('mouseup', function (event) {
        alert('This alert should not show up!');
    }, false);
    

    这很好,因为第三个参数是useCapture,它指定是否应该使用事件的捕获阶段。

    当你切换到 jQuery 版本时:

    $('#outer').on('mouseup', function (event) {
        alert('This alert should not show up!');
    }, false);
    

    我认为正在发生的事情是第三个参数只是覆盖您的事件处理程序函数并导致事件处理程序除了return false;之外什么都不做,这显然不是要发生的事情。

    来自jQuery docs(强调添加):

    触发事件时执行的函数。 值 false 是 也允许作为简单返回的函数的简写 错误

    删除false 参数,jQuery 版本也能正常工作:

    $('#outer').on('mouseup', function (event) {
        alert('This alert should not show up!');
    });
    

    注意alert 应该 出现,所以addEventListener 方法工作正常。请参阅@Pointy 的回答了解为什么会这样。

    【讨论】:

      【解决方案2】:

      当您在文档级别使用.on() 时,您正在等待事件一直冒泡到该点。任何中间容器的事件处理程序都已被调用。

      事件“冒泡”是浏览器查找向作为事件的实际原始接收者的元素的父级注册的事件处理程序的过程。它在 DOM 树中向上工作。文档级别是检查的最后级别。因此,在.on() 注册的处理程序在达到该级别之前不会运行。同时,首先到达“外部”级别的另一个事件处理程序,并由浏览器执行。

      因此,使用.on() 注册的处理程序中的return false; 几乎没有用,就像对event.stopPropagation() 的调用一样。除此之外,将原生事件处理程序注册与像 jQuery 这样的库所做的工作混合起来可能是一个非常糟糕的主意,除非你真的知道自己在做什么。

      今天刚刚有a question asked almost exactly like this one

      【讨论】:

      • return false 在 jQuery 事件处理程序中也执行 event.preventDefault()event.stopPropagation()
      • 我创建这个结构的原因是因为 a.link 元素是动态添加的,并且我需要以某种方式阻止 outer div 处理该特定事件 - 怎么能我做到了吗?所以基本上你的意思是: $(document).on('mouseup', 'a.link' ...) 等于: $('a.link').live('mouseup', ... )?
      • 是的 - 像.live().delegate() 或新的.on() 这样的机制可以工作的唯一方法是通过冒泡,并且冒泡是由内而外的。相反,您可以确保动态添加元素的事件侦听器在元素添加到 DOM 时直接绑定到元素。
      • 谢谢!他们为什么不推荐使用live() 方法是有道理的——最初我认为无需将侦听器显式附加到动态添加的元素就可以实现类似的功能
      • @Pointy:我知道这个答案是几个月前的,但是 +1 用于解释差异以及为什么它可能导致将本机与 jQuery 甚至绑定混合的问题。我从来没有意识到有这么大的区别,因为我自己从来没有混合过它们。谢谢。
      猜你喜欢
      • 2012-12-19
      • 2014-05-12
      • 1970-01-01
      • 2017-02-04
      • 1970-01-01
      • 2011-01-24
      • 2015-07-04
      • 2016-04-26
      • 2022-07-16
      相关资源
      最近更新 更多