Prevent parent click from firing if a specific child is click - javascript

I want to prevent my parent click method to fire if the user clicks on a specific child element.
Example html:
<div data-type="parent_holder" style="width:500px; height:500px;">
<div data-type="child_holder" style="width:50px; height:50px; position:absolute;">
click
</div>
</div>
Example js:
I use jquery on in my js because I attach the element dynamically to a sortable list.
$( "#sortable" ).on( "click", "[data-type=parent_holder]", function() {
alert('parent');
});
$( "#sortable" ).on( "click", "[data-type=child_holder]", function() {
alert('child');
});
So what I want is, when a user clicks on the parent_holder it should alert parent, but if the user clicks on the child_holder it should alert child, and not alert parent.
I have searched stackoverflow and I have tried many of the suggestions, like :not(), bubbling, stopPropagation(), but I can't seem to get the right result.

Sounds like event propagation is happening in your case,
just avoid that by using event.stopPropagation()
Try,
$( "#sortable" ).on( "click", "[data-type=child_holder]", function(e) {
e.stopPropagation();
alert('child');
});
DEMO

Use:
e.stopPropagation();
or
return false;
in child click handler to prevent event propagation from parent events.

If for some reason you still need the click event to bubble from child element, you could filter instead the target inside parent click handler:
$( "#sortable" ).on( "click", "[data-type=parent_holder]", function(e) {
if(!$(e.target).is('[data-type=parent_holder]')) return;
alert('parent');
});
--DEMO--

Related

Use one() in inline onclick attribute

I have a function that is triggered on an inline onclick.
What I want is for that function to get called only once but don't know how to do that with an inline onclick. It's working at the moment but runs everytime the user clicks rather than just once.
This is how I have it:
HTML
<div class= "container" onclick="modal('#modal')"></div>
I have tried having it as a Jquery function as follows and remove the above click but that is not working either:
$(".container").on( "click", modal( '#modal') {
alert( "The event happened!" );
});
Any idea how to make it so the function only runs once?
Thank you
If you wish to use jQuery's one(), you'll need to remove the onclick from the HTML, and change the JS to read:
$( ".container" ).one( "click", function() {
alert( "The event happened!" );
});
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<div class= "container">Container</div>
This way, the alert() will only show on the first click.
If you wish to use the on() as stated in your question, use $(this).off('click'); to remove the event listener after the fist press:
$( ".container" ).on( "click", function() {
alert( "The event happened!" );
$(this).off('click');
});
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<div class= "container">Container</div>

Cancel other trigger events attached to element

I have an element that has numerous event triggers attached to it.
How do I cancel all of those events (without editing the code of those triggers) and add a new one.
So far, I have tried this without luck:
$(document).ready(function() {
$( document ).on( 'click', '#element', function(e) {
$(this).off();
e.preventDefault();
e.stopPropagation();
e.stopImmediatePropagation();
// now that it's cancelled, do NEW stuff below
alert('test');
});
});
Clone the element for remove all event listener and replace the element with new cloned element.
$(document).ready(function() {
$( document ).on( 'click', '#element', function(e) {
var clonedElem = $(this).clone();
$( this ).replaceWith( clonedElem )
});
});
your code should do it
$(this).off()
removes all event listeners. However, you want to check if 'this' is really the element you want to address. In your code 'this' would be the Window object, not #element

jquery DOM mutation

I have made this:
<span class="a">test 1</span><div></div>
Why .b does not activate the alert?
$( ".a" ).click(function() {
$('div').html('<span class="b">test 2</span>');
});
$( ".b" ).click(function() {
alert("Hello");
});
I do not understand how to detect the mutation of the DOM.
since .b is created after the query was done. when you call $(".b") in your script nothing is found, and the click event is not attached to it. You can solve it by attaching the event to the document like so:
$(document).on("click", ".b", function () {
alert("hello");
});
The click() binding you're using is called a "direct" binding which will only attach the handler to elements that already exist. It won't get bound to elements created in the future. To do that, you'll have to create a "delegated" binding by using on().
$('div').on("click", ".b", function () {
alert("hello");
});
The selector runs on execution, meaning that .b was already searched for when the page loaded, rather than after you added the dom.
To demonstrate how selectors run in line, the code works if you define it right after appending the element:
$( ".a" ).click(function() {
$('div').html('<span class="b">test 2</span>');
$( ".b" ).click(function() {
alert("Hello");
});
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<span class="a">test 1</span><div></div>
However, the correct way of doing this would be to define a parent-based selector. The following is setting a click event to the parent that filters the target for the .b selector.
$( ".a" ).click(function() {
$('div').html('<span class="b">test 2</span>');
});
$(document.body).on("click", ".b", function () {
alert("Hello");
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<span class="a">test 1</span><div></div>

Z-index not working

Hi I have a close button on the container and i am trying to create two different click events. When a user click on the close button then it should call the close button click event and when click on the container it should call the container click event.
The container click event is working fine but when clicking on the close button then it is calling both close click event and the contianer click event. I have set the z-index:9999 to the close div but still this is not working.
This is my Jsfiddle code .
$( "#close-button-landscape" ).click(function() {
alert( "close button click" );
});
$( "#container" ).click(function() {
alert( "container click" );
});
Thanks for the answers. In the Jquery i can use event.stopPropagation(); but what if click events are not using Jquery and pure javascript . See this updated Jsfiddle, then how to stop the bubble event?
What you should do is to do something called stop propagation
$( "#close-button-landscape" ).click(function(evt) {
evt.stopPropagation();
alert( "close button click" );
});
this prevents the click event from bubbling up to the container one as well.
Note: z-index won't affect anything in this case. z-index only paints elements out of order ... and the area which #container covers is larger than the one that the close button affects
The button is still in the container so you have to stop the click getting through:
$('#close-button-landscape').click(function(event)
{
event=event||window.event;
if(event.stopPropagation)
{
event.stopPropagation();
}
else
{
event.cancelBubble=true;
}
}
Just use stopPropagation
$( "#close-button-landscape" ).click(function(e) {
e.stopPropagation();
alert( "close button click" );
});
$( "#container" ).click(function() {
alert( "container click" );
});

click event being removed on previous elements

answer:
/* I bound the events via the parent instead of binding it
on each span tag individually. this allowed me to manipulate
the span tags uniquely. ( thank you Jason P ) */
$( '.selected-option-wrapper' ).on( 'click', 'span', function() { });
disclaimer:
I am losing my mind.
details:
I am trying to list in html a bunch a options that a user selected via a ul/li dropdown. I want the user to click on a li a and have part of the html within the a tag, placed in a separate div.
For example:
html
// html within the li tag that I want cloned over
<a id="met" class="item-1" href="#">
<div class="left check-wrapper">
<span class="gicon-ok"></span>
</div>
<div class="hide item-display"> // exact element to be moved over
<span class="gicon-remove-sign left remove-option-item"></span>
<div class="left">Metallic Thread</div>
</a>
javascript
$( '.options' ).find( 'a' ).on( 'click', function( e ) {
ind_option_html = $( this ).find( '.item-display' ).clone();
/* attach a click event to the span tag */
ind_option_html.find( 'span' ).on( 'click', function() {
console.log( this );
});
/* this is in a $.each loop that appends each new ind_option_html */
$( '.selected-option-wrapper' ).show().append( ind_option_html );
});
problem
whenever I click just one li a the function fires fine, the this for the span tag is logged out. but what is amazing is that when a user clicks another li a the click event is placed on ONLY the most recent span tag.
Where is the onclick event going with the first span tag?
I'm not sure why you're having the problem you are, but you can probably avoid it using event delegation. Instead of binding the event handler each time, do it like this when the DOM is ready:
$('.selected-option-wrapper').on('click', 'span', function() { ... });
See on(), and the section about direct and delegated events.
Where is the initial var ind_option_html (or is it an accidental global)? Looks like all of the instances of the click handler use the same reference, which is always the last one to be processed.
So your fix would be:
ind_option_html = $( this ).find( '.item-display' ).clone();
to:
var ind_option_html = $( this ).find( '.item-display' ).clone();

Categories