8

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?

1
  • 1
    did you try the 'live' binding? Commented Nov 24, 2011 at 18:10

5 Answers 5

14

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");
});
Sign up to request clarification or add additional context in comments.

4 Comments

If you're going to select all the elements, you may as well use click... live isn't necessary with this code and is inefficient.
"Use of the .live() method is no longer recommended since later versions of jQuery offer better methods that do not have its drawbacks. In particular, the following issues arise with the use of .live()" read more: api.jquery.com/live
live does not work for me, nothing happens on click!
This post is pretty old and LIVE does not exists anymore. The new way to do it is a delegate. I've updated my answer.
9

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.

Comments

1

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');
});

1 Comment

I suspect this will work but @Niels example looks a little cleaner. Thank you.
1

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");
});

Comments

0

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.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.