【问题标题】:How to prevent delegated handlers on a parent without preventing default in jQuery?如何在不阻止 jQuery 的默认设置的情况下阻止父级上的委托处理程序?
【发布时间】:2011-03-10 19:44:18
【问题描述】:

有什么方法可以防止来自<a> 的点击触发其父级上的委托点击处理程序,同时允许<a> 的默认行为发生(导航到href)。

这里有一个例子来说明我在问什么。

<div class="top">
    <div class="middle">
        <a href="google.com" class="link">link</a>
    </div>
</div>

还有我的 JavaScript:

$(".top").delegate(".middle", "click", function(event) {
   alert("failure");
});

$(".top").delegate(".link", "click", function(event) {
   // ???
});

在这种情况下,我希望在单击链接时导航到 google.com,但在我离开时一定不能看到 alert("failure")

解决方案有一些限制:

  1. 所有事件处理程序都必须从 $(".top") 委派出去,因为我可能在页面中有数千个这样的处理程序。
  2. 导航必须使用浏览器默认行为完成,而不是window.location = $(this).attr("href") 或类似的

使用普通事件绑定,我可以在&lt;a&gt; 的点击处理程序中执行e.stopPropagation(),但由于委托的性质,这将不起作用。 jQuery 提供了另一种称为.stopImmediatePropagation() 的方法,它描述了我想要的内容(阻止当前元素上的其他处理程序,在这种情况下是包含委托处理程序的元素),但在这种情况下实际上并没有完成它。这可能是.delegate() 中的一个错误,我不确定。

&lt;a&gt; 的单击处理程序返回false 将阻止其他处理程序运行,但也会执行.preventDefault(),因此浏览器将无法导航。基本上,我想知道return false; 做了什么e.stopImmediatePropagation(); e.preventDefault(); 没有。根据文档,它们应该是等效的。

对于上述代码的现场演示,这里有一个 JSFiddle:https://jsfiddle.net/CHn8x/

【问题讨论】:

    标签: javascript jquery events delegation


    【解决方案1】:

    event.stopImmediatePropagation() 确实是您所追求的,但请记住这里的顺序很重要,因为 .delegate() 在同一级别上侦听,因此您需要反转您的绑定,如下所示:

    $(".top").delegate(".link", "click", function(event) {
      event.stopImmediatePropagation();
    });
    $(".top").delegate(".middle", "click", function(event) {
      if(!event.isPropagationStopped())
        alert("failure");
    });
    

    Here's a working version of your demo with this change

    您绑定处理程序的顺序是它们将执行的顺序,因此您需要 .link 处理程序执行并停止传播另一个处理程序运行之前,使用 event.isPropagationStopped()event.isImmediatePropagationStopped().

    这在不同级别通常不是问题,但由于.delegate()正在监听相同元素,这确实很重要。

    【讨论】:

    • 我写问题时,一位同事也找到了该解决方案,这似乎有效。这很不方便,因为您必须修改其他处理程序。在我们的例子中,它现在可以工作,因为我们有一个包装和附加点击处理程序的元层,所以我们可以在通用包装处理程序中进行检查。谢谢!
    • 顺便说一句,顺序似乎并不重要。
    • @bcherry - 如果您不使用最新的 jQuery,.live().delegate() 在内部使用)并不总是尊重文档中的元素顺序;)
    • 函数名也很有趣,在 attr, val, css, html 之后。你有 stopImmediatePropagation 和 isImmediatePropagationStopped... :)
    • @galambalazs - 他们只是没有重命名 ;) developer.mozilla.org/en/DOM/event.stopPropagation
    猜你喜欢
    • 2015-08-18
    • 1970-01-01
    • 2016-05-27
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2018-02-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多