How do I prevent event propagation on link click?
Asked Answered
H

4

11

When I click on my a-tag, I do not want the parent's event to trigger. If the child had a normal event listener, it could be prevented by event.stopPropagation(), but how do I do it when there is no "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>
Hangover answered 10/8, 2018 at 14:35 Comment(0)
C
7

Approach 1

If the child had a normal event listener, it could be prevented by event.stopPropagation()

Yes.

but how do I do it when there is no "event"?

There is an event. You are just not listening for it.

You could solve the problem by listening on the child element:

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>

Approach 2

Alternatively, you could check the target of the event and see if it is unacceptable.

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>
Carom answered 10/8, 2018 at 14:46 Comment(0)
F
10

Simply add a click listener to the link, on which you do event.stopPropagation();. This will prevent the click on the child to bubble (and thus, trigger a click on the parent).

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>
Freshet answered 10/8, 2018 at 14:47 Comment(0)
C
7

Approach 1

If the child had a normal event listener, it could be prevented by event.stopPropagation()

Yes.

but how do I do it when there is no "event"?

There is an event. You are just not listening for it.

You could solve the problem by listening on the child element:

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>

Approach 2

Alternatively, you could check the target of the event and see if it is unacceptable.

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>
Carom answered 10/8, 2018 at 14:46 Comment(0)
C
4

The event object is available in the onclick handler as well:

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

Inspired from this.

⚠️ Incompatible with Internet Explorer, however it works fine with Edge (tested on v89).

Cementum answered 18/3, 2021 at 21:44 Comment(0)
A
-1

try this.

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

calling event.stopImmediatePropagation(); will gives you the expected results, as per my experience.

Academy answered 10/8, 2018 at 15:24 Comment(6)
You appear to have copy pasted code from my answer … breaking it as you did so because blacklist is not defined in your version … which also failing to understand the question. Your addition will stop events firing on ancestors of "parent", but the goal was to stop the event on "parent" if the link inside "parent" was clicked.Carom
Sorry I just got the code from up and I thought its from the question. wait I’ll editAcademy
+I wanted to highlighted the stopImmediatePropagation() function.. not the codeAcademy
As I pointed out in my previous comment, calling stopImmediatePropagation on "parent" won't solve the problem.Carom
yeah agreed, here ID should be the child element's ID.Academy
So now your answer is essentially the same as the two that were written half an hour before.Carom

© 2022 - 2024 — McMap. All rights reserved.