即使在调用 jQuery 的 stopPropagation() 之后,单击事件处理程序也会无意中冒泡

发布于 2024-09-07 03:32:55 字数 1045 浏览 1 评论 0原文

我试图为列表中“li”元素中的不同元素使用不同的委托单击处理程序。示例:

<ul id='myList'>
  <li>
    <p>First item.</p>
    <button>button1</button>
    <button>button2</button>
  </li>
  <li>
    <p>Second item.</p>
    <button>button1</button>
    <button>button2</button>
  </li>
</ul>

当用户单击(任何项目的)button1 时,我想捕获该事件,并停止传播(对于button2 实例也是如此)。用户单击父 li 元素将是一个不同的处理程序:

$('#myList').delegate('li', 'click', function() {
    alert("You clicked a parent <li> item!");
});

$('#myList').delegate('button', 'click', function(event) {
    event.stopPropagation();
    event.stopImmediatePropagation();
    alert("You clicked a button (but which one?)!");
});

因此,一个问题是,如何为 button1 实例拥有一个委托,并为 Button2 实例拥有另一个委托?上面示例中的第二个委托在单击按钮时确实会触发,但 event.stopPropagation() 似乎不起作用,因为父 li 项的处理程序仍然被调用,

------ Update ---- ----------

还尝试调用 event.stopImmediatePropagation(),但没有效果,父处理程序仍然被调用。

谢谢

I'm trying to have different delegate click handlers for different elements within "li" elements in a list. Example:

<ul id='myList'>
  <li>
    <p>First item.</p>
    <button>button1</button>
    <button>button2</button>
  </li>
  <li>
    <p>Second item.</p>
    <button>button1</button>
    <button>button2</button>
  </li>
</ul>

when the user clicks button1 (of any item) I want to grab that event, and stop propagation (same for button2 instances). The user clicking the parent li element would be a different handler:

$('#myList').delegate('li', 'click', function() {
    alert("You clicked a parent <li> item!");
});

$('#myList').delegate('button', 'click', function(event) {
    event.stopPropagation();
    event.stopImmediatePropagation();
    alert("You clicked a button (but which one?)!");
});

So one issue is, how do I have a delegate for button1 instances, and another for button2 instances? The second delegate in the example above does fire when a button is clicked, but event.stopPropagation() doesn't seem to work as the handler for the parent li item still gets called,

------ Update --------------

Also trying to call event.stopImmediatePropagation(), no effect though, parent handler still being called too.

Thank you

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

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

发布评论

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

评论(4

狂之美人 2024-09-14 03:32:56

也许在父级:

$('#myList').delegate('li', 'click', function(event) {
    if (!$(event.target).is('button')) {
        alert("You clicked a parent <li> item!");
    }
});

Maybe in the parent:

$('#myList').delegate('li', 'click', function(event) {
    if (!$(event.target).is('button')) {
        alert("You clicked a parent <li> item!");
    }
});
手心的海 2024-09-14 03:32:56

事实上,它应该可以工作,我尝试单步执行 jQuery 代码,但无济于事。相反,我做了这个:

(function(){
  var el = document.getElementsByTagName("li");
  var i = el.length;

  while (i--)
    el[i].onclick = function () {
      alert("You clicked a parent <li> item!");
    };

  el = document.getElementsByTagName("button");
  i = el.length;

  while (i--)
    el[i].onclick = function (event) {
      var e = event || window.event;

      e.stopPropagation();
      e.cancelBubble = true;
      alert("You clicked a button (but which one?)!");
    };

})();

它按照你想要的方式工作(尽管没有在 IE 中进行测试)。我太累了,现在,也许明天,我不想进一步研究这个问题。

回答您的其他问题:我认为您确实应该将 idclass 添加到您的

Indeed, it should work, and I tried to step through the jQuery code, but to no avail. Instead, I made this:

(function(){
  var el = document.getElementsByTagName("li");
  var i = el.length;

  while (i--)
    el[i].onclick = function () {
      alert("You clicked a parent <li> item!");
    };

  el = document.getElementsByTagName("button");
  i = el.length;

  while (i--)
    el[i].onclick = function (event) {
      var e = event || window.event;

      e.stopPropagation();
      e.cancelBubble = true;
      alert("You clicked a button (but which one?)!");
    };

})();

which works the way you want it to work (not tested in IE, though). I'm to tired to look into this further, now, perhaps tomorrow.

To answer your other question: I think you should really add ids or classes to your <button>s, so you can easily test which button got called.

冰魂雪魄 2024-09-14 03:32:56

您可以尝试event.stopImmediatePropagation()。从理论上讲,您所拥有的应该有效,因此扩展它可能会有所帮助。

You can try event.stopImmediatePropagation(). Theoretically, what you have should work, so expanding it might help.

追我者格杀勿论 2024-09-14 03:32:56

原因是 .delegate() 只会在点击事件向下冒泡时执行点击函数myList 的子元素。然后它将执行每个匹配的委托,因此它在您的示例中正确调用了这两个委托,因为当单击到达 myList 时,它已经通过了 BUTTON 和 LI。

由于您在 BUTTON 之前绑定 LI,因此 LI 委托在被调用的列表中是第一个,因此您可以先绑定 BUTTON 委托,然后它应该可以工作。

The reason is that .delegate() will only execute the click functions once the click event bubbles down through the child elements to myList. It will then perform every delegate that matches, so it is correctly calling both in your example because by the time click arrives at myList it has passed through both a BUTTON and a LI.

Since you bound LI before BUTTON the LI delegate is first in the list that get called, you could just bind the BUTTON ones first and it should work.

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