I have 2 elements nested called blanket and blanket-content and I want to recognize the clicks done to the parent alone.
<div id="blanket">
<div id="blanket-content"></div>
</div>
The issue that I'm having is that when I'm clicking the child it is triggering the parent on click. I've tried different methods yet I was unsuccessful.
I have tried these to play around with my code;
$('#blanket').on('click', function(ev) {
alert(ev.currentTarget.id); //
});
^ This triggers the click on div as normal and state the parent id even when the child is clicked.
$('#blanket-content').on('click', function(ev) {
alert(ev.currentTarget.id);
});
^ This doesn't trigger anything
What I want to achieve is when I click on blanket-content nothing will happen, but when I click on blanket I want to do something.
One easy solution is to stop the event propagation in a click handler of the blanket-content, so that it will trigger the parent element's click handler.
You can use Event.stopPropagation() to do that
$('#blanket').on('click', function(ev) {
alert(ev.currentTarget.id); //
});
$('#blanket-content').on('click', function(ev) {
ev.stopPropagation()
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.1/jquery.min.js"></script>
<div id="blanket">blanket
<div id="blanket-content">blanket-content</div>
</div>
Another solution(why) is to check whether the click happened in the blanket-content element inside the blanket click handler
$('#blanket').on('click', function(ev) {
if (!$(ev.target).closest('#blanket-content').length) {
alert(ev.currentTarget.id); //
}
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.1/jquery.min.js"></script>
<div id="blanket">blanket
<div id="blanket-content">blanket-content</div>
</div>
No need to do more. Just add ev.stopPropagation(); inside #blanket-content click event.
<div id="blanket">PARENT
<div id="blanket-content">CHILD</div>
</div>
$('#blanket').on('click', function(ev) {
alert(ev.currentTarget.id); //
});
$('#blanket-content').on('click', function(ev) {
ev.stopPropagation();
alert(ev.currentTarget.id);
});
Check here: https://jsfiddle.net/92jwad1w/
Try preventing the Default action, stop propogation doesn't always work if it is still being referenced.
$('#blanket').on('click', function(event){
$(event).preventDefault();
});
this will stop the default action of a click event and will work well.
for more information, go here
Related
I am trying to create an accordion inside of an accordion... and I am struggling a little.
essentially, I have a div .applicant, which upon click adds a class .expand, which sets the height to auto, but, inside of the .applicant div, I have another div .applicant-child, which SHOULD do the same thing, and does... but, .applicant closes when you click .applicant-child, meaning you have to click the .applicant again to open view the nested element.
Here is my code:
HTML
<div class="row">
<div class="col-sm-12">
<div class="applicant">
<p><b>PS4 Tournaments</b></p>
<div class="applicant-child">
<p>lalal</p>
<p>lalal</p>
</div>
</div>
</div>
</div>
jQuery
$('.applicant').click(function(){
if ($(this).hasClass('expand')) {
$(this).removeClass('expand');
} else {
$( this ).addClass('expand');
}
});
$('.applicant-child').click(function(){
if ($(this).hasClass('expand')) {
$(this).removeClass('expand');
} else {
$( this ).addClass('expand');
}
});
I could simply remove $(this).removeClass('expand'); from .appliant, but we'll be displaying a lot of data, so that isn't ideal.
How do I solve this?
Thanks in advance :)
That's just event bubbling an expected behaviour.
See this link on jQuery on how to disable the click-Event to bubble up the DOM and triggering the event on your parent element.
Basically, you just have to do this:
$('.applicant-child').click(function(event){
event.stopPropagation();
if ($(this).hasClass('expand')) {
$(this).removeClass('expand');
} else {
$( this ).addClass('expand');
}
});
You want to prevent bubbling. Bubbling means, that the event you are reacting to is being passed up the DOM to the parent objects, until it reaches the window.
Check out the "event.stopPropagation()" method, which will prevent any subsequent listeners from reacting.
On your click handler if you pass through a param:
$('.applicant').click(function(event){
console.log(event.target);
if ($(this).hasClass('expand')) {
$(this).removeClass('expand');
} else {
$( this ).addClass('expand');
}
});
you can use event.target to check if you are clicking on the parent or the child and decide on what action to take from there.
Say I have
<div id="mydiv">
<div class="myclass">
<span class="otherclass"></span>
and many other classes...
</div>
</div>
I want to capture the click event on .mydiv but not inside .myclass.
I tried .mydiv:not(.myclass) but it doesn't seem to work. I think it's because I might be clicking on the otherclass so the :not(.myclass) is not working. How can I get the area I want to get? Thanks!
make #mydiv clickable, do whatever you wish, and stop event propagation from .myclass, so the event will not bubbleup from myclass to mydiv
$('#mydiv').click(function(){
// do anything
})
// stop event propagation
$('.myclass').click(function(e){
e.stopPropagation();
})
You can click on mydiv id and write your code in that function and on .myclass click event you simply write return false to stop further execution of function.
$('#mydiv').click(function(){
// stuff your code here
});
//Use `return false` instead of `e.stopPropagation();`
$('.myclass').click(function(e){
return false;
})
e.stopPropagation() is dangerous please read Documentation
Calling .off() will remove an event handler
$("#mydiv").on('click', function () {
alert("You clicked mydiv");
});
$(".myclass").off('click', function () {
});
or like this
$(".myclass").off();
JS FIDDLE
JS Fiddle Link
I am dynamically adding some elements and my div looks like:
<div class="knock" href="#">
<!-- Do Something if links are not clicked -->
Google
Facebook
</div>
And my on script is:
$(".knock").on("click", function(){
console.log("Link not clicked");
alert("Link not Clicked");
});
My Problem, I do not want to fire the alert when the links are clicked. Is there a way out?
You can write anchor tag event and stop event Propagation of the event to upper DOM elements so that alert only comes up when the div is actually clicked, but not when some anchor tag inside div is clicked:
$(".knock").on('click',"a",function(event){
event.stopPropagation();
})
FIDDLE:
http://jsfiddle.net/hbac7vbh/2/
event.stopPropagation:
The event.stopPropagation() method stops the bubbling of an event to parent elements, preventing any parent event handlers from being executed.
See details here on jquery official page
Just determine if the a is clicked based on the event that is passed.
Updated Example
$(".knock").on("click", function(e){
if(!$(e.target).is('a')){
console.log("Link not clicked");
alert("Link not Clicked");
}
});
Add this to your js:
$(".knock a").on("click", function(e) {
return false;
});
Why not add another method as
$('a').on('click',function(e){
e.stopPropagation();
});
This will stop porpagation of the chaininvocation of events on parent elements.
See updated Fiddle
I'm trying to get a .click() event to work on a div.content except if clicked on something with a specific class, say, .noclick. Example html:
<div class="content">
<a href="#" class="noclick">
</div>
Doing this doesn't work because the <a> tag is not technically in the selection:
$('.content').not('.noclick').click(function(){/*blah*/});
How can I get the click function to work if I click anywhere on .content except something with class .noclick?
You'd have to exclude them from within the callback:
$('.content').click(function(e) {
if ($(e.target).hasClass('noclick')) return;
});
Or stop the event from leaving those elements:
$('.noclick').click(function(e) {
e.stopPropagation();
});
I would go with the second one. You can just drop it and your current code (minus the .not()) will work.
$('.content').click(function(event) {
// ...
}).find('.noclick').click(function(event) {
event.stopPropagation();
});
$('.content').click(function(e){
if(!$(e.target).is('.noclick')){
// Handle click event
}
});
$('.content').
on('click', '.noclick', function(){return false;}).
click(function(){alert("click")})
cancels clicks on '.noclick', yet fires clicks elsewhere
http://jsfiddle.net/FshCn/
I'm trying to have a div get a new class (which makes it expand) when being clicked, and get it back to the old class (which makes it close) when clicking on a cancel link inside that div.
<div class="new-discussion small">
<a class="cancel">Cancel</a>
</div>
<script>
$('.new-discussion.small').click(function() {
$(this).addClass("expand").removeClass("small");
});
$('a.cancel').click(function() {
$('.new-discussion.expand').addClass("small").removeClass("expand");
});
</script>
Now, adding the expand class works flawlessly, but closing the panel after clicking on the cancel link only works when I remove this code:
$('.new-discussion.small').click(function() {
$(this).addClass("expand").removeClass("small");
});
So I guess this must be preventing the second function to work, but I really can't figure out why.
Any ideas?
Thanks!
Try this
$('a.cancel').click(function() {
$('.new-discussion.expand').addClass("small").removeClass("expand");
return false;
});
Reason may be your click event is getting propagated to parent which is also listening to click event.
Since your a element is inside the .new-discussion element, when you click on the a, it also fires the click event on the parent element because the event is bubbling up.
To fix it, you can stop the propagation of the event by calling e.stopPropagation();. That will prevent any parent handlers to be executed.
$('a.cancel').click(function(e) {
e.stopPropagation();
$('.new-discussion.expand').addClass("small").removeClass("expand");
});
Since the link is inside the <div>, it's using both click methods at once. It might help to do a check to see if the container is already open before proceeding:
<script>
$('.new-discussion.small').click(function() {
if ($(this).hasClass("small")) {
$(this).addClass("expand").removeClass("small");
}
});
$('a.cancel').click(function() {
$(this).parent('.expand').addClass("small").removeClass("expand");
});
</script>