10

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>
Zebrastian
  • 421
  • 2
  • 7
  • 18

4 Answers4

8

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>
connexo
  • 53,704
  • 14
  • 91
  • 128
6

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>
Quentin
  • 914,110
  • 126
  • 1,211
  • 1,335
3

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).

Maxime Pacary
  • 22,336
  • 11
  • 85
  • 113
-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.

  • 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. – Quentin Aug 10 '18 at 15:51
  • Sorry I just got the code from up and I thought its from the question. wait I’ll edit – Ishara Jayaweera Aug 10 '18 at 15:51
  • +I wanted to highlighted the stopImmediatePropagation() function.. not the code – Ishara Jayaweera Aug 10 '18 at 15:53
  • 1
    As I pointed out in my previous comment, calling `stopImmediatePropagation` on "parent" won't solve the problem. – Quentin Aug 10 '18 at 15:54
  • yeah agreed, here ID should be the child element's ID. – Ishara Jayaweera Aug 10 '18 at 15:57
  • So now your answer is essentially the same as the two that were written half an hour before. – Quentin Aug 10 '18 at 16:04