JQuery Using toggleClass() inside a .click() of the same class doesn't seem to work
So what I'm trying to do is sort of like the thumbs up/thumbs down voting system on youtube using jquery, implying that once a user has voted, both divs(images, doesn't matter what) will become unavailable for that specific post.
So far, to do so, I use a .click() inside which a toggleClass() will change its own class, I can see that the class changes if I inspect the DOM, but why is the .click() still working on the new class ?
//TO BE CALLED WHEN USER CLICKS VOTE FORGIVENESS
$('.voteUp').click(function() {
var id = $(this).closest("article").attr("id");
//Make it开发者_如何学Go impossible to vote again
$(this).toggleClass('voteUp votedUp');
$(this).parent().find('.voteDown').toggleClass('voteDown votedDown');
});
And my html (php)
<article class='yellowSheet' id='57'>
<div class="title">
<h1>StuffUp says :</h1>
<p class="story">What happened ?</p>
</div>
<div class="entryContent">
<p>guy, 2011-06-28 17:11:48</p>
</div>
<div class="voting">
<img class="voteUp" src="images/thumbsUp.png" /></div>
<img class="voteDown" src="images/thumbsDown.png" /></div>
<div class="storyBottom"></div>
</article>
What I don't understand is why after toggling class, I still can click on the new class-"votedDown" since that class doesn't have a .click method ?
Thank You
The class name is only the means you use to match an element: the click
handler is registered on the element itself and will be called whether it still exposes the class or not.
You can use live() to register an event handler that will only be called if the element still matches the initial selector:
$(".voteUp").live("click", function() {
// Your event handler.
});
You've already bound a click event to the object. You cannot remove the class an expect the click event to come with it. What you want is to call this:
$(this).unbind('click');
I would actually remove the voteUp and add votedUp.
$(this).removeClass('voteUp').addClass('votedUp');
If you want to toggle a class, possibly just toggle 'votedUp', not 'voteUp votedUp'. If you have a click event assigned to 'voteUp', simply adding on 'votedUp' in your toggle won't remove that click bind.
.click binds an event handler to all the entities that match your selector at 'run time' - so despite removing the class, the entity still has a click event bound.
You can do one of two things. Either use:
$('.voteUp').live('click', function() {
// etc
} );
'live' behaves in the manner that you are expecting 'click' to, and only activates when you click on something that matches its selector - and it analyses this every time you click.
Or you can unbind the event manually in the event handler, eg:
$('.voteUp').bind('click.voteUp', function(e) {
$(this).unbind('click.voteUp');
// and the rest of what you want to do;
});
This second example also uses namespaced event handlers, a neat feature in jquery, which means only your named event handler will be removed.
Not sure if it matters at this point, but you have an extra "</div>
", I reformatted what you have to make the issue clearer:
<div class="voting">
<img class="voteUp" src="images/thumbsUp.png" />
</div> <!-- Extra close div -->
<img class="voteDown" src="images/thumbsDown.png" />
</div>
So I don't think the find() in this statement is going to match anything:
$(this).parent().find('.voteDown').toggleClass('voteDown votedDown');
It actually binds to the element and not the class. The class name is just used for the initial lookup.
In this case you would either want to use the .unbind()
method to unbind the click event after it's been clicked $(this).unbind('click');
OR
use the .one()
method which would only allow the element to be clicked once.
$('.voteUp').one('click', function() {...
精彩评论