Jquery. toggleclass to not toggle on click on child - javascript

I'm using :
$("#cart").click(function(e){
$('#cart').load('index.php?route=module/cart #cart > *');
var e=window.event||e;
$("#cart").toggleClass("active");
e.stopPropagation();
$(document).click(function(e){
$("#cart").removeClass("active");
$('#cart').live('mouseleave', function() {
});
});
});
now the problem is that whenever I click on a child of #cartit toggles the class, which I don't want. How can I make it only toggle when I click on #cart and not on the child ?

To check if an event handler has been called because of event bubbling, compare this to event.target within the event handler:
$('#cart').on('click', function(event){
if(this === event.target){
// $('#cart') was clicked
} else {
// event has bubbled up from a descendant of $('#cart')
}
});

Related

How can I avoid an event from firing on a parent element while clicking on the child?

I have a table with some data inside. When I click on a element, it adds a class .active to :
$('#someId').on('click', 'tr', function (e) {
var target = $(this).find(".target");
var prev = target.html();
timeCell.html(target.data('prev'));
timeCell.data('prev', prev);
if ($(this).hasClass('active')) {
$(this).removeClass('active');
} else {
$(this).addClass('active');
}
});
As you can see after clicking on tr, users could see some icons instead of previous data (.target) and I want them to click on icons ("prev") that call some other functions. But when the icons are clicked, a click on a parent element is execute too. How can I avoid this?
----
If anybody needs help in this case - here's the solution!
$('#someId').on('click', 'tr', function (e) {
var senderName = e.target.tagName.toLowerCase();
if (senderName === 'div') {
//do some staff
} else {
var target = $(this).find(".target");
var prev = target.html();
timeCell.html(target.data('prev'));
timeCell.data('prev', prev);
if ($(this).hasClass('active')) {
$(this).removeClass('active');
} else {
$(this).addClass('active');
}
});
The reason why the click event on the parent <tr> element is being fired is due to event bubbling. You can stop the click event emitted within the child node from bubbling up (and being captured by the click event listener bound to the parent), is to simply call event.stopPropagation() in the child click event, i.e.:
$('#someId').on('click', 'tr', function (e) {
// Stop click event from bubbling up to parent and getting captured
e.stopPropagation();
// Rest of the logic
var target = $(this).find(".target");
var prev = target.html();
timeCell.html(target.data('prev'));
timeCell.data('prev', prev);
if ($(this).hasClass('active')) {
$(this).removeClass('active');
} else {
$(this).addClass('active');
}
});

Using :not() to ignore clicks on children links?

In a script I'm writing with JQuery I'm trying to add a click handler to a div, but ignoring clicks on the children a tags inside it.
You can see a JSFiddle of how I'm currently trying (and failing) to make it happen here: http://jsfiddle.net/q15s25Lx/1/
$(document).ready(function() {
$(document).on('click', '.post:not(a)', function(e) {
alert($(this).text());
});
});
<div class="post">This is some text in a div. Click me please.</div>
In my real page, the a tags all have their own click handlers, so I need to be able to listen for those concurrently.
So, ideally I'd like to use something like the :not() selector to ignore clicks on this particular handler.
Is something like this possible?
You'll need to add another handler that acts on the anchor and stops the event from propagating:
$(document).on('click', '.post a', function (e) {
e.stopPropagation();
e.preventDefault();
});
Without this, when you click the a the event bubbles up to the parent .post, and the handler fires on that anyway.
You need to stop event propagation to child elements using .stopPropagation():
$(document).on('click', '.post a', function(e) {
e.stopPropagation();
});
Working Demo
Just return false; in the end of event handler.
$(document).on('click', '.post', function (e) {
alert($(this).text());//will show entire text
});
$(document).on('click', '.post a', function (e) {
alert($(this).text());//will show 'text'
return false;
});
working fiddle: http://jsfiddle.net/q15s25Lx/2/
return false will server as both e.preventDefault() &
e.stopPropagation()
Try to stop the event from bubbling up the DOM tree using stopPropogation()
$(document).ready(function() {
$(document).on('click', '.post a', function(e) {
e.stopPropagation();
alert($(this).text());
});
});
Fiddle Demo
All of the other posts did not explain why your code failed. Your selector is saying : Find an element that has the class post and is not an anchor. It is NOT saying if a child was clicked and was an achor do not process.
Now there are two ways to solve it. One is to prevent the click from bubbling up from the anchors. You would add another listener on the anchors.
$(document).on('click', '.post a', function (evt) {
evt.stopPropagation(); //event will not travel up to the parent
});
$(document).on('click', '.post', function (evt) {
console.log("Click click");
});
Or the other option is not to add a second event, but check what was clicked.
$(document).on('click', '.post', function (evt) {
var target = $(evt.target); //get what was clicked on
if (target.is("a")) { //check to see if it is an anchor
return; // I am an anchor so I am exiting early
}
console.log("Click click");
});
Or jsut let jquery handle it all for you. return false
$(document).on('click', '.post:not(a)', function() {
alert($(this).text());
return false;
});

Add/remove class on right click

I'm trying to add a class on right-click of an element and then remove it when anything else on the page is clicked.
I'm using jQuery.
My function is this so far:
$(".classElement").live('mousedown', function(e) {
if( (e.which == 3) ) {
$(".classElement").addClass("active");
}
e.preventDefault();
}).live('contextmenu', function(e){
e.preventDefault();
});
However, this adds the "active" class to all ".classElement" in the doc, rather than the individual one being clicked. I want to only add the class to the element being clicked.
Also, how can I remove the class when anything else is clicked?
You can removClass active on click of body element, but for this you have to stop event propagation when you are clicking on current element.
$(document).on('mousedown','.classElement', function(e) {
e.preventDefault();
if( (e.which == 3) ) {
$(this).addClass("active");
}
e.stopPropagation();
}).on('contextmenu','.classElement', function(e){
e.preventDefault();
});
$(document.body).click(function(){
$(".classElement").removeClass("active");
});
You can use $(this) to target current clicked element, so you can do:
$(this).addClass("active");
instead of:
$(".classElement").addClass("active");
Also, since .live() was removed since version 1.9, you should use .on() instead.
to target specific element:
$(this).addClass("active");
and to remove it when anything else is clicked, add this:
$(window).one("click", function(){
$(this).removeClass("active");
});
This adds a one time only click event listener to the window.
Use this code
$(".classElement").live('contextmenu', function(e){
e.preventDefault();
if( (e.which == 3) ) {
$(this).addClass("active");
}
});
and then remove class on document click
$(document).click(function(){
$(".classElement").removeClass("active");
});

jQuery/js event on click on container but not on element IN the container

I would like to have a click-event on a container, but not when I click on an element within the container:
$('.container').click(function(event) {
history.back(1);
});
But the history.back() should not be called, when I click on
<div class="container">Link</div>
Is it possible to exclude the link from the container-event?
You could do:
$('.container').click(function(event) {
if(event.target.nodeName.toLowerCase() == 'div' ) {
// code
}
});
use event.stopPropagation(); in click event handler:
event.stopPropagation();
Try this :
$('.container').click(function(event) {
if(event.target === event.currentTarget) history.back(1);
//(event.target === this) => Equivalent.
});

click elsewhere

i have problem with click event. click to another element with event(click), doesn't count like click elsewhere. I want active one element or none.
demo: http://jsfiddle.net/WP4RH/
code:
$('span').click(function(){
var $this = $(this);
if($this.hasClass('active')){
$this.removeClass('active')}
else $this.addClass('active');
$('div').click(function(){
if (!$this.has(this).length) {
$this.removeClass('active');
}
});
return false;
});
Add this at the beginning of your span event handler:
$('.active').removeClass('active');
Demo
This is assuming that you want multiple clicks on the same span to retain active. If you don't want that, then let me know and I can modify the code.
​
For starters, You should move the div handler outside and then removeClass based on div element.
$('span').click(function(e) {
e.stopPropagation();
$(this).parent().find('span').removeClass('active');
$(this).toggleClass('active');
});
$('div').click(function() {
$(this).find('span').removeClass('active');
});
DEMO: http://jsfiddle.net/WP4RH/1/
Don't bind a click handler inside a click handler, just check if the target is the div or the span inside the click handler instead. Also, when adding the active class to this, just remove it on any sibling span :
$('span').on('click', function(){
$(this).toggleClass('active').siblings('span').removeClass('active');
});
$('div').on('click', function(e){
if (e.target == this) $('span').removeClass('active');
});
FIDDLE
​
If you want to keep the toggle-off functionality when the span itself has been clicked, then you can use the following. Also, note that you're binding an event handler each time a span is clicked.
http://jsfiddle.net/WP4RH/7/
$("span").click(function() {
$(this).siblings("span").removeClass("active"); // remove from other spans
$(this).toggleClass("active"); // toggle this span
return false;
});
​
$("div").click(function() {
$(this).find("span").removeClass("active"); // remove from all spans
});

Categories

Resources