如何在不阻止 jQuery 中默认值的情况下阻止父级上的委托处理程序?

发布于 2024-09-07 12:21:33 字数 1446 浏览 3 评论 0原文

有什么方法可以防止 的点击触发其父级上的委托点击处理程序,同时允许发生 的默认行为(导航至 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") 或类似的

使用正常的事件绑定,我可以执行 e. stopPropagation() 的点击处理程序中,但由于委托的性质,这不起作用。 jQuery 提供了另一种名为 .stopImmediatePropagation() 的方法,它描述了我想要的内容(防止当前元素上的其他处理程序,在本例中为保存委托处理程序的元素),但在这种情况下实际上并没有完成它。我不确定这可能是 .delegate() 中的错误。

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

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

Is there any way to prevent a click from an <a> triggering delegated click handlers on its parent, while allowing the the <a>'s default behavior to occur (navigating to the href).

Here's an example that illustrates what I'm asking.

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

And my JavaScript:

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

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

In this case, I want to be navigated to google.com when I click the link, but must NOT see the alert("failure") on my way out.

There are a few restrictions to the solution:

  1. All event handlers must be delegated off of $(".top"), as I potentially have thousands of these in the page.
  2. The navigation must be accomplished using browser default behavior, rather than window.location = $(this).attr("href") or similar

Using normal event binding, I could do an e.stopPropagation() in a click handler for the <a>, but that won't work due to the nature of delegation. jQuery provides another method called .stopImmediatePropagation() that describes what I want (preventing other handlers on current element, in this case the element that holds the delegated handlers), but does not actually accomplish it in this case. That might be a bug in .delegate(), I'm not sure.

Returning false from the <a>'s click handler will prevent the other handler from running, but will also do a .preventDefault(), so the browser will not navigate. Basically, I'm wondering what return false; does that e.stopImmediatePropagation(); e.preventDefault(); does not. Based on the docs, they should be equivalent.

For a live demo of the above code, here's a JSFiddle: https://jsfiddle.net/CHn8x/

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

花伊自在美 2024-09-14 12:21:33

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

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

这是经过此更改的演示的工作版本

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

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

event.stopImmediatePropagation() is indeed what you're after, but remember that order matters here since .delegate() listens at the same level, so you need to reverse your bindings, like this:

$(".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

The order you bound the handlers is the order they will execute, so you need that .link handler to execute and stop the propagation before the other handler runs, checking it with event.isPropagationStopped() or event.isImmediatePropagationStopped().

This normally isn't an issue at different levels, but since .delegate() is listening on the same element, it does matter.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文