Undefined
Undefined

Reputation: 1929

JQuery click event not working correctly after class change

I have JQuery script similar to this:

$('.follow_link').click(function(){
  // Do some stuff
  $(this).removeClass();
  $(this).addClass("unfollow_link");
});

$('.unfollow_link').click(function(){
  // Do some stuff
  $(this).removeClass();
  $(this).addClass("follow_link");
});

My problem is that after I change the class the link is still refering to it's old class' click event. Is there a way of rebinding? Or am I doing this a bad way?

Upvotes: 8

Views: 8574

Answers (5)

Niels
Niels

Reputation: 49929

You can use this, both functions in 1:

$('.unfollow_link, .follow_link').live("click", function(){
    $(this).toggleClass("follow_link unfollow_link");
});

See toggleClass, and the live function

.toggleClass( className ) classNameOne or more class names (separated by spaces) to be toggled for each element in the matched set.

Edit for new jQuery versions 1.6.4+

Since the live function does not exists anymore, here is a replacement:

$('body').on("click", '.unfollow_link, .follow_link', function(){
    $(this).toggleClass("follow_link unfollow_link");
});

Upvotes: 14

Guillaume Renoult
Guillaume Renoult

Reputation: 966

Note: I just had this issue even if the on() function and still have the issue on JQuery 1.10,

Actually I resolved the problem by replacing:

$('.unfollow_link, .follow_link').live("click", function(){
     $(this).toggleClass("follow_link unfollow_link");
});

By

$(document).on('click','.unfollow_link, .follow_link', function(){
    $(this).toggleClass("follow_link unfollow_link");
});

Upvotes: 1

lonesomeday
lonesomeday

Reputation: 237865

The problem is that jQuery works by selecting elements (that's what $('.follow_link') does) and then binding an event handler to those elements (that's what .click*function(){ does). It doesn't matter if the class changes.

Javascript has a feature called event bubbling. This means that ancestor elements are notified of events on their descendants. This means that you can test selectors when the event occurs, rather than on document ready.

jQuery makes this easy with the on function:

$(document.body).on('click', '.follow_link', function(){
  // Do some stuff
  $(this).removeClass();
  $(this).addClass("unfollow_link");
}).on('click', '.unfollow_link', function(){
  // Do some stuff
  $(this).removeClass();
  $(this).addClass("follow_link");
});

Note that this function was introduced in jQuery 1.7. For compatibility with previous versions, use delegate.

Upvotes: 9

Marc B
Marc B

Reputation: 360702

Try:

$('.follow_link, .unfollow_link').click(function() {
    newclass = $(this).hasClass('follow_link') ? 'unfollow_link' : 'follow_link';
    $(this).removeClass().addClass(newclass)
});

edit: Niels' solution is much nicer.

Upvotes: 0

Jasper
Jasper

Reputation: 76003

It would be better to give each of the links a third class that designates that they are part of a group. Something like a_link:

$('.a_link').bind('click', function () {
    $(this).toggleClass('follow_link unfollow_link');
});

Upvotes: 1

Related Questions