如何在链接点击时阻止事件传播?

11

当我点击a标签时,我不想触发父元素的事件。如果子元素有一个普通的事件监听器,可以通过event.stopPropagation()来阻止事件冒泡,但是当没有"event"时该怎么做呢?

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
</head>
<body>
<div id="parent" style="width:100px; height:100px; background-color: red">
    <a id="child" href="https://i.kym-cdn.com/entries/icons/facebook/000/013/564/doge.jpg">Text</a>
</div>
<script>
    document.getElementById("parent").addEventListener("click", function () {
        alert("Oh no, you clicked me!");
    });
</script>
<script src="test.js"></script>
</body>
</html>
4个回答

8

只需在链接上添加一个点击监听器,然后使用event.stopPropagation();。这将阻止子元素上的点击事件冒泡(从而触发父元素的点击事件)。

document.getElementById("parent").addEventListener("click", function() {
  console.log('parent received click');
});

document.getElementById("child").addEventListener("click", function(e) {
  e.preventDefault(); // this line prevents changing to the URL of the link href
  e.stopPropagation(); // this line prevents the link click from bubbling
  console.log('child clicked');
});
<div id="parent" style="width:100px; height:100px; background-color: red">
  <a id="child" href="https://i.kym-cdn.com/entries/icons/facebook/000/013/564/doge.jpg">Text</a>
</div>


6

方法一

如果子元素有一个普通的事件监听器,可以通过event.stopPropagation()来防止它发生

是的。

但是当没有“event”时该怎么办?

其实是有事件的,只是你没有监听它。

你可以在子元素上添加事件监听器来解决问题:

document.getElementById("parent").addEventListener("click", function() {
  alert("Oh no, you clicked me!");
});

document.querySelector("a").addEventListener("click", function(e) {
  e.stopPropagation();
});
<div id="parent" style="width:100px; height:100px; padding: 1em; background-color: #aaa">
  <a id="child" href="https://placeimg.com/200/200/nature/sepia">Text</a>
</div>


方法二

或者,您可以检查事件的target并查看是否不可接受。

const blacklist = [document.querySelector("a")];

document.getElementById("parent").addEventListener("click", function(e) {
  if (blacklist.includes(e.target)) {
    return;
  }
  alert("Oh no, you clicked me!");
});
<div id="parent" style="width:100px; height:100px; padding: 1em; background-color: #aaa">
  <a id="child" href="https://placeimg.com/200/200/nature/sepia">Text</a>
</div>


4

event 对象同样可以在 onclick 处理函数中使用:

<a id="child" href="https://i.kym-cdn.com/entries/icons/facebook/000/013/564/doge.jpg"
  onclick="event.stopPropagation()">Text</a>

受到这篇文章的启发。

⚠️ 不兼容Internet Explorer,但在Edge上运行良好(已测试v89)。


-1

试一下这个。

document.getElementById(id-here).addEventListener("click", function(e) {
  e.stopImmediatePropagation();
  console.log("clicked");
});

根据我的经验,调用event.stopImmediatePropagation();将会给你期望的结果。


你似乎复制粘贴了我的答案中的代码...但是由于 blacklist 在你的版本中未定义,导致它无法正常运行...而且还没有理解问题。你的代码将停止在“parent”的祖先上触发事件,但目标是在单击“parent”内部的链接时停止“parent”的事件。 - Quentin
抱歉,我刚刚从上面获取了代码,以为它是来自问题。等一下,我会进行编辑。 - Ishara Jayaweera
我想要强调 stopImmediatePropagation() 函数,而不是代码。 - Ishara Jayaweera
1
正如我在之前的评论中指出的那样,在“父级”上调用stopImmediatePropagation并不能解决问题。 - Quentin
是的,同意,这里的ID应该是子元素的ID。 - Ishara Jayaweera
现在你的答案基本上与半小时前写的两个答案一样。 - Quentin

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