How do I prevent a parent's onclick event from firing when a child anchor is clicked?

JavascriptJqueryEvent Propagation

Javascript Problem Overview


I'm currently using jQuery to make a div clickable and in this div I also have anchors. The problem I'm running into is that when I click on an anchor both click events are firing (for the div and the anchor). How do I prevent the div's onclick event from firing when an anchor is clicked?

Here's the broken code:

JavaScript

var url = $("#clickable a").attr("href");

$("#clickable").click(function() {
	window.location = url;
	return true;
})

HTML

<div id="clickable">
	<!-- Other content. -->
	<a href="http://foo.com">I don't want #clickable to handle this click event.</a>
</div>

Javascript Solutions


Solution 1 - Javascript

Events bubble to the highest point in the DOM at which a click event has been attached. So in your example, even if you didn't have any other explicitly clickable elements in the div, every child element of the div would bubble their click event up the DOM to until the DIV's click event handler catches it.

There are two solutions to this is to check to see who actually originated the event. jQuery passes an eventargs object along with the event:

$("#clickable").click(function(e) {
    var senderElement = e.target;
    // Check if sender is the <div> element e.g.
    // if($(e.target).is("div")) {
    window.location = url;
    return true;
});

You can also attach a click event handler to your links which tell them to stop event bubbling after their own handler executes:

$("#clickable a").click(function(e) {
   // Do something
   e.stopPropagation();
});

Solution 2 - Javascript

Use stopPropagation method, see an example:

$("#clickable a").click(function(e) {
   e.stopPropagation();
});

As said by jQuery Docs:

> stopPropagation method prevents the event from bubbling up the DOM > tree, preventing any parent handlers from being notified of the event.

Keep in mind that it does not prevent others listeners to handle this event(ex. more than one click handler for a button), if it is not the desired effect, you must use stopImmediatePropagation instead.

Solution 3 - Javascript

Here my solution for everyone out there looking for a non-jQuery code (pure javascript)

document.getElementById("clickable").addEventListener("click", function( e ){
    e = window.event || e; 
    if(this === e.target) {
        // put your code here
    }
});

Your code wont be executed if clicked on parent's childs

Solution 4 - Javascript

If you do not intend to interact with the inner element/s in any case, then a CSS solution might be useful for you.

Just set the inner element/s to pointer-events: none

in your case:

.clickable > a {
    pointer-events: none;
}

or to target all inner elements generally:

.clickable * {
    pointer-events: none;
}

This easy hack saved me a lot of time while developing with ReactJS

Browser support could be found here: http://caniuse.com/#feat=pointer-events

Solution 5 - Javascript

you can also try this

$("#clickable").click(function(event) {
   var senderElementName = event.target.tagName.toLowerCase();
   if(senderElementName === 'div')
   {
       // do something here 
   } 
   else
   {
      //do something with <a> tag
   }
});

Solution 6 - Javascript

Inline Alternative:

<div>
    <!-- Other content. -->
    <a onclick='event.stopPropagation();' href="http://foo.com">I don't want #clickable to handle this click event.</a>
</div>

Solution 7 - Javascript

Writing if anyone needs (worked for me):

event.stopImmediatePropagation()

From this solution.

Solution 8 - Javascript

If you have multiple elements in the clickable div, you should do this:

$('#clickable *').click(function(e){ e.stopPropagation(); });

Solution 9 - Javascript

Using return false; or e.stopPropogation(); will not allow further code to execute. It will stop flow at this point itself.

Solution 10 - Javascript

I compare to ev.currentTarget when this is not available (React, etc).

$("#clickable").click(function(e) {
    if (e.target === e.currentTarget) {
        window.location = url;
        return true;
    }
})

Solution 11 - Javascript

Here's an example using Angular 2+

For example, if you wanted to close a Modal Component if the user clicks outside of it:

// Close the modal if the document is clicked.

@HostListener('document:click', ['$event'])
public onDocumentClick(event: MouseEvent): void {
  this.closeModal();
}

// Don't close the modal if the modal itself is clicked.

@HostListener('click', ['$event'])
public onClick(event: MouseEvent): void {
  event.stopPropagation();
}

Solution 12 - Javascript

var inner = document.querySelector("#inner");
var outer = document.querySelector("#outer");
inner.addEventListener('click',innerFunction);
outer.addEventListener('click',outerFunction);

function innerFunction(event){
  event.stopPropagation();
  console.log("Inner Functiuon");
}

function outerFunction(event){
  console.log("Outer Functiuon");
}

<!DOCTYPE html>
<html>
<head>
  <meta charset="utf-8">
  <meta name="viewport" content="width=device-width">
  <title>Pramod Kharade-Event with Outer and Inner Progration</title>
</head>
<body>
<div id="outer" style="width:100px;height:100px;background-color:green;">
  <div id="inner" style="width:35px;height:35px;background-color:yellow;"></div>
</div>
</body>
</html>

Solution 13 - Javascript

If it is in inline context, in HTML try this:

onclick="functionCall();event.stopPropagation();

Solution 14 - Javascript

e.stopPropagation() is a correct solution, but in case you don't want to attach any event handler to your inner anchor, you can simply attach this handler to your outer div:

e => { e.target === e.currentTarget && window.location = URL; }

Solution 15 - Javascript

You need to stop the event from reaching (bubbling to) the parent (the div). See the part about bubbling here, and jQuery-specific API info here.

Solution 16 - Javascript

You can check whether the target is not your div-element and then issue another click event on the parent after which you will "return" from the handle.

$('clickable').click(function (event) {
    let div = $(event.target);
    if (! div.is('div')) {
       div.parent().click();
       return;
    }
    // Then Implement your logic here
}

Solution 17 - Javascript

Here is a non jQuery solution that worked for me.

<div style="background:cyan; width:100px; height:100px;" onclick="if (event.srcElement==this) {console.log('outer');}">
    <a style="background:red" onclick="console.log('inner');">Click me</a>
</div>

Solution 18 - Javascript

To specify some sub element as unclickable write the css hierarchy as in the example below.

In this example I stop propagation to any elements (*) inside td inside tr inside a table with the class ".subtable"

$(document).ready(function()
{    
   $(".subtable tr td *").click(function (event)
   {
       event.stopPropagation();
   });
   
});

Solution 19 - Javascript

In case someone had this issue using React, this is how I solved it.

scss:

#loginBackdrop {
position: absolute;
width: 100% !important;
height: 100% !important;
top:0px;
left:0px;
z-index: 9; }

#loginFrame {
width: $iFrameWidth;
height: $iFrameHeight;
background-color: $mainColor;
position: fixed;
z-index: 10;
top: 50%;
left: 50%;
margin-top: calc(-1 * #{$iFrameHeight} / 2);
margin-left: calc(-1 * #{$iFrameWidth} / 2);
border: solid 1px grey;
border-radius: 20px;
box-shadow: 0px 0px 90px #545454; }

Component's render():

render() {
    ...
    return (
        <div id='loginBackdrop' onClick={this.props.closeLogin}>
            <div id='loginFrame' onClick={(e)=>{e.preventDefault();e.stopPropagation()}}>
             ... [modal content] ...
            </div>
        </div>
    )
}

By a adding an onClick function for the child modal (content div) mouse click events are prevented to reach the 'closeLogin' function of the parent element.

This did the trick for me and I was able to create a modal effect with 2 simple divs.

Solution 20 - Javascript

ignoreParent() is a pure JavaScript solution.

It works as an intermediary layer that compares the coordinates of the mouse click with the coordinates of the child element/s. Two simple implementation steps:

1. Put the ignoreParent() code on your page.

2. Instead of the parent's original onclick="parentEvent();", write:

onclick="ignoreParent(['parentEvent()', 'child-ID']);"

You may pass IDs of any number of child elements to the function, and exclude others.

If you clicked on one of the child elements, the parent event doesn't fire. If you clicked on parent, but not on any of the child elements [provided as arguments], the parent event is fired.

ignoreParent() code on Github

Solution 21 - Javascript

If a child element is clicked, then the event bubbles up to the parent and event.target !== event.currentTarget.

So in your function, you can check this and return early, i.e.:

var url = $("#clickable a").attr("href");
$("#clickable").click(function(event) {
    if ( event.target !== event.currentTarget ){
    	// user clicked on a child and we ignore that
    	return;
    }
    window.location = url;
    return true;
})

Solution 22 - Javascript

This is what you are looking for

mousedown event. this works on every DOM elements to prevent javascript focus handler like this:

$('.no-focus').mousedown(function (e) {
   e.prevenDefault()

   // do stuff
}

in vue.js framework, you can use modifier like this:

<span @mousedown.prevent> no focus </span>

> Note that using on the input will prevent text selection handler

Solution 23 - Javascript

add a as follows:

<a href="http://foo.com" onclick="return false;">....</a>

or return false; from click handler for #clickable like:

  $("#clickable").click(function() {
        var url = $("#clickable a").attr("href");
        window.location = url;
        return false;
   });

Solution 24 - Javascript

All solution are complicated and of jscript. Here is the simplest version:

var IsChildWindow=false;

function ParentClick()
{
    if(IsChildWindow==true)
    {
        IsChildWindow==false;
        return;
    }
    //do ur work here 	
}


function ChildClick()
{
    IsChildWindow=true;
    //Do ur work here    
}

Solution 25 - Javascript

<a onclick="return false;" href="http://foo.com">I want to ignore my parent's onclick event.</a>

Attributions

All content for this solution is sourced from the original question on Stackoverflow.

The content on this page is licensed under the Attribution-ShareAlike 4.0 International (CC BY-SA 4.0) license.

Content TypeOriginal AuthorOriginal Content on Stackoverflow
QuestionJonathon WatneyView Question on Stackoverflow
Solution 1 - JavascriptRex MView Answer on Stackoverflow
Solution 2 - JavascriptCleitonView Answer on Stackoverflow
Solution 3 - JavascriptSabazView Answer on Stackoverflow
Solution 4 - JavascriptHooman AskariView Answer on Stackoverflow
Solution 5 - JavascriptRashad ValliyengalView Answer on Stackoverflow
Solution 6 - JavascriptMatt WyethView Answer on Stackoverflow
Solution 7 - JavascriptBahadir TasdemirView Answer on Stackoverflow
Solution 8 - JavascriptGlorious KaleView Answer on Stackoverflow
Solution 9 - JavascriptImamudin NaseemView Answer on Stackoverflow
Solution 10 - JavascriptSzalai LaciView Answer on Stackoverflow
Solution 11 - JavascriptSteve BrushView Answer on Stackoverflow
Solution 12 - JavascriptPramod KharadeView Answer on Stackoverflow
Solution 13 - JavascriptGlenoView Answer on Stackoverflow
Solution 14 - JavascriptgovizloraView Answer on Stackoverflow
Solution 15 - JavascriptMatt BallView Answer on Stackoverflow
Solution 16 - JavascriptnafiuView Answer on Stackoverflow
Solution 17 - JavascriptDuncanView Answer on Stackoverflow
Solution 18 - Javascriptuser3202819View Answer on Stackoverflow
Solution 19 - JavascriptClaudioView Answer on Stackoverflow
Solution 20 - JavascriptFomView Answer on Stackoverflow
Solution 21 - Javascriptzıəs uɐɟəʇsView Answer on Stackoverflow
Solution 22 - JavascriptJavad EbrahimiView Answer on Stackoverflow
Solution 23 - JavascriptTheVillageIdiotView Answer on Stackoverflow
Solution 24 - JavascriptratneshView Answer on Stackoverflow
Solution 25 - Javascriptandres descalzoView Answer on Stackoverflow