Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

jQuery click() still being triggered after .clickable class is removed

I've got a click event assigned to a div of a particular class. When the click occurs, the class is removed from the div. However, you can still click the div and the click() event is triggered (even though the class has since been removed). Here's an example:

HTML:

<div class="clickable">
  <p>Click me</p>
</div>

JavaScript/jQuery:

$('.clickable').click(function() {
  $(this).removeClass('clickable');
  $(this).addClass('not-clickable');
  alert('Clicked!');
});

I can see the classes are removed and added (as the colour of the text changed as per my CSS). However, you are still able to click the div multiple times and the alert() will still appear.

This also seems to occur in reverse; so if I add the clickable class to a div, the code in $('.clickable').click(function() {...}); doesn't run (but visually, the div changes as per the new styles).

How can I make it so that the click events match up to the classes, even after jQuery adds/removes the clickable class?

like image 415
Dan Murfitt Avatar asked Aug 16 '12 09:08

Dan Murfitt


4 Answers

When you attach an event handler to a DOM element, it stays intact. The class is just a way to reference the element, and changing the class will not unbind the event handlers, for that you will have to manually unbind the handler, and if using jQuery 1.7+ on() and off() is the way to go :

$('.clickable').on('click', function() {
  $(this).removeClass('clickable').addClass('not-clickable').off('click');
});

this would make the element clickable only once, and you could just use the built in one() function instead, as that will unbind the handler automagically after the first click :

$('.clickable').one('click', function() {
  $(this).removeClass('clickable').addClass('not-clickable');
});
like image 78
adeneo Avatar answered Nov 13 '22 12:11

adeneo


You can use this

$(document.body).delegate('.clickable', 'click', function(e){
    $(this).removeClass('clickable');
    alert('Clicked!');
});

From jQuery version 1.7 delegate() is superseded by the on()

$(document.body).on('click', '.clickable', function(e){
    $(this).removeClass('clickable');
    alert('Clicked!');
});

Or

$('.clickable').on('click', function(e){
    $(this).removeClass('clickable').off('click');
    alert('Clicked!');
});

Also you can use method one() - it's equal to bind, but occurs once

$('.clickable').one('click', function(e){
    alert('Clicked!');
});
like image 35
Ivan Turovets Avatar answered Nov 13 '22 10:11

Ivan Turovets


$(document).on('click', '.clickable', function() {
  $(this).removeClass('clickable');
  $(this).addClass('not-clickable');
  alert('Clicked!');
});
like image 3
Michal Klouda Avatar answered Nov 13 '22 12:11

Michal Klouda


$('.clickable').live('click',function() {
  $(this).removeClass('clickable');//remove the class
  $(this).unbind('click');//to remove the click event
  $(this).addClass('not-clickable');
  alert('Clicked!');
});
like image 2
Hilmi Avatar answered Nov 13 '22 10:11

Hilmi