简体   繁体   中英

jQuery - onclick event does not change class after second click

Functionality:

When I click on element with class thumb_like or thumb_unlike then I will add/remove like for image with POST. Element with class thumb_count will increase/decrease by action of user. If he like add 1 to current count etc...

thumb_unlike is default status where user did not liked image

Problem:

When I click on element with class thumb_like / thumb_unlike it will do as told, but second click do not change class and user can add/remove more than just 1 like ( increase thumb_count by 1 )

HTML markup:

<div class="image_box">
    <div class="image">...</div>
    <div class="image_info">
        <div class="thumb_like" data-id="1"></div>
        <div class="thumb_count">10</div> likes | 0 comments
    </div>
</div>

<div class="image_box">
    <div class="image">...</div>
    <div class="image_info">
        <div class="thumb_unlike" data-id="2"></div>
        <div class="thumb_count">55</div> likes | 0 comments
    </div>
</div>

Javascript

$(document).ready(function() {

    $(".thumb_unlike").click(function () {
        var image_id = $(this).attr('data-id');
        var count = $(this).next(".thumb_count").text();
        $(this).next(".thumb_count").html(parseInt(count) + 1)
        $.post('..url..' + image_id);

        $(this).removeClass();
        $(this).addClass('thumb_like');
    });

    $(".thumb_like").click(function () {
        var image_id = $(this).attr('data-id');
        var count = $(this).next(".thumb_count").text();
        $(this).next(".thumb_count").html(parseInt(count) - 1)
        $.post('..url..' + image_id);

        $(this).removeClass();
        $(this).addClass('thumb_unlike');
    });
});

Listeners get attached to elements when the function gets called. The way you have it, listeners are attached to the thumbs themselves. I think the easiest way around this would be to attach the listener to a parent element and delegate to the thumbs. Like so:

$('.parent_div').on('click', '.thumb_like', function() {
  //thumb_like code here
});

$('.parent_div').on('click', '.thumb_unlike', function() {
  //thumb_like code here
});

If your intent is to have the ability to toggle - I'd recommend one function. You can do this without even adjusting your HTML like this:

$(function() {
    $('body').on('click', '.thumb_like, .thumb_unlike', function() {
        var image_id = $(this).attr('data-id'),
            isLike = $(this).hasClass('thumb_like');
        $(this).toggleClass('thumb_like thumb_unlike')
               .next('.thumb_count')
               .text(function(_, i) { return +i + (isLike ? 1 : -1); });
        $.post('..url..', { 
            id: image_id,
            action: isLike ? 'like' : 'unlike'
        });
    });
});

This binds one function up at a higher div as evan suggests , but also allows for much less code, fewer event handlers, and is (IMO) easier to maintain since you're dealing with the logic once. You can additionally use a single server-side route for like & unlike.

You can play with it in a jsfiddle here .

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM