How do I prevent a parent's onclick event from firing when a child anchor is clicked?
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();
});
Prevent firing its parent's click event on Clicking a child element
Use event.stopPropagation() to prevents the event from bubbling up the DOM tree.
Example:
$('.subMenu').click(function (e) {
$(this).children('ul').slideToggle(250);
e.stopPropagation();
});
This will fix your issue.
Stop parent event firing on child element click
Without jQuery you can use event delegation and determine to act using Element.closest()
document.addEventListener(`click`, handle);
function handle(evt) {
console.clear();
if (!evt.target.closest(`.innerUl`) && evt.target.closest(`#testUl`)) {
console.log(`You clicked (something within) the first li of ul#testUl`);
}
}
<ul id="testUl">
<li>
<a href="#">Test A</a>
<div class="innerUl">
<ul>
<li>Inner A</li>
<li>Inner B</li>
<li>Inner C</li>
</ul>
</div>
</li>
</ul>
Prevent parent click when click on child
You need to prevent default action (which is focusing on input) by calling ev.preventDefault
$(function() {
$('#child').click(e => {
e.preventDefault()
console.log('click on child')
})
$('#parent').click(() => {
console.log('click on parent')
})
})
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<label for="parent">
<span id="child">Click Me</span>
</label>
<input type="text" id="parent">
Trigger click event on parent but prevent click event on children
As you mentioned in the comment you want to stop the goRed
method for certain condition then do this inside your function.
if(event.target.id=='content') return; // Add your condition here and return.
Instead of the event.target.id=='content'
condition check for your condition when you want it to execute.
UPDATE
You can check this condition $(this).parent().is('#container')
to check if your content is inside container
.
SNIPPET
$(document).on('click', '#container', goGreen )
$(document).on('click', '.content', goRed )
function goGreen( event )
{
$(this).find('.content').addClass('green')
}
function goRed( event )
{
if($(this).parent().is('#container')) return; // Add your condition here and return.
$(this).addClass('red')
}
.content {
display: inline-block;
width: 100px;
height: 100px;
border: 1px solid #000;
cursor: pointer;
}
#container{
display: inline-block;
padding: 3px;
border:2px solid red;
}
.green {
background-color: lightgreen;
}
.red {
background-color: tomato;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div id="container">
<a class="content"></a>
</div>
<a class="content"></a>
How to block click event on child element using parent element
For vanilla JavaScript, there's also a way to prevent the child events from triggering even they're assigned beforehand.
You may add a click event to the parent, set useCapture
by assigning the third parameter to true
in the addEventListener
function and then e.stopPropagation
in the function body.
This will make sure this event triggers before normal event phases, so all its child click events will not trigger. It also keeps the buttons clickable and will not alter their appearance.
document.querySelector('#parent').addEventListener('click', e => e.stopPropagation(), true);
<div id="parent">
<div>
<button onclick="console.log('a')">a</button>
</div>
<button onclick="console.log('b')">b</button>
<button onclick="console.log('c')">c</button>
</div>
Preventing Child from firing parent's click event
You have to add an event listener to the inner child and cancel the propagation of the event.
In plain JS something like
document.getElementById('inner').addEventListener('click',function (event){
event.stopPropagation();
});
is sufficient. Note that jQuery provides the same facility:
$(".inner-div").click(function(event){
event.stopPropagation();
});
or
$(".inner-inner").on('click',function(event){
event.stopPropagation();
});
How to stop firing parent click event when child event clicked
You can pass & use the event object and use stopPropagation
function methods(e) {
console.log(' Parent function')
}
function method2(e) {
console.log(' Child function');
event.stopPropagation();
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<div onclick='methods()'>
<div></div>
<div>
<button onclick='method2(event)'>Button</button>
</div>
</div>
How do I prevent the onClick of the parent going off when clicking the child?
Use event.stopPropagation()
or event.stopImmediatePropagation()
these stop event bubbling and end bubble of events where it is called.
Related Topics
Detect iOS Version Less Than 5 with JavaScript
JavaScript Console.Log() in an iOS Uiwebview
iOS Wkwebview Not Showing JavaScript Alert() Dialog
Error: No Firebase App '[Default]' Has Been Created - Call Firebase App.Initializeapp()
How to Have a Host and Container Read/Write the Same Files with Docker
Include a JavaScript File in Shiny App
Web Worker Settings for Chrome
Batch File > JavaScript > Winscp > Check If File Exists
Rails 4: Disable Turbolinks in a Specific Page
How to Execute JavaScript in Ruby Written Webdriver Test
Ruby's ||= (Or Equals) in JavaScript
Scoping the Results for Rails3 Jquery Autocomplete Plugin
Phonegap - Save Image from Url into Device Photo Gallery
Viable Options for Running Nodejs on Android (Aug 2017)
How to Pass Parameters Rendered from Backend to Angular2 Bootstrap Method