0

I made a like system but when I click on the like button it will run but I have to refresh the page for me to then be able to click on the unlike button even though it is showing up ? please help me I need it to be able to be clickable and work right after each other....

<script type="text/javascript">
$(document).ready(function(){
 $('.like').click(function(){
  if($(this).attr('title')=='like'){
   $.post('/like.php',{imid:$(this).attr('id'),action:'like'});
    $(this).removeClass('like').addClass('unlike');
    $(this).attr('title','unlike');
  }
});
});
</script>
<script type="text/javascript">
$(document).ready(function(){
    $('.unlike').click(function(){
   if($(this).attr('title')=='unlike'){
    $.post('/like.php',{imid:$(this).attr('id'),action:'unlike'});
     $(this).removeClass('unlike').addClass('like');
     $(this).attr('title','like');
    }
  });
});
</script>
Adam
  • 6,539
  • 3
  • 39
  • 65

2 Answers2

1

I think @Steven Britton's answer should work - except he's missing the event for the likes.

The following works for me:

<script type="text/javascript">
$(function(){
    $('body')
    .on('click', '.like', function(){
        // Do whatever to register action
        $(this).removeClass('like').addClass('unlike').attr('title', 'unlike');
    })
    .on('click', '.unlike', function(){
        // Do whatever to register action
        $(this).removeClass('unlike').addClass('like').attr('title', 'like');
    });
});
</script>

I don't see the need for the test (if title = unlike) since you have different classes for like/unlike anyway. If you are going to do a test I would recommend doing it by testing for classes - testing for texts in the title will break as soon as you change to texts (e.g. translate the page). The texts are part of the presentation, the classes part of the data structure.

You could give all the links a common class (e.g. "like-unlike") in addition to the like or unlike class and use something like the following:

<script type="text/javascript">
$(function(){
    $('body').on('click', '.like-unlike', function(){
        if( $(this).hasClass('like') ){     
            // Do whatever to register action
            $(this).removeClass('like').addClass('unlike').attr('title', 'unlike');
        } else if( $(this).hasClass('unlike') ){
            // Do whatever to register action
            $(this).removeClass('unlike').addClass('like').attr('title', 'like');
        } else {
            // SHould never happen - log error?
        }
    });
});
</script>

To answer the comment about how to use a delegated event: .on is (when used like this) using a delegated event. I am binding the event to the document body, not to the like buttons. When the user clicks the like buttons the event bubbles up to the body at which point my delegated event is run (assuming the element clicked matches the selector I give as second argument to .on (.e.g ".like-unlike" in my final example).

The difference is that the original code was saying "when the page loads find all elements with class 'like' and attach this click event to them and all elements with class 'unlike' and attach that click event to them". When the click event is run it changes the class from like to unlike. But because the element did not have class "unlike" when the document loaded it was not found then and did not get that event. In fact it still has the "like" event handler even after the class is changed to "unlike" since that event handler was attached to the element when the page loaded. The fact that the list of elements to attach the event to was found using a specific class doesn't matter - those on the list get that event handler and keep it.

By attaching to the body using .on in it's three-argument form we are then running events based on what class the element has when it is clicked, instead of what class it had when the document loaded.

My second example (using the like-unlike class) would actually work as a non-delegated event as well, but I still think delegated events are better here - you might end up loading content with ajax requests or something.

Adam
  • 6,539
  • 3
  • 39
  • 65
0

Give this a shot (by using the ON, you're setting an event handler on classes that haven't been applied yet):

<script type="text/javascript">
$(document).ready(function(){
    $(document).on('click','.unlike', function(){
   if($(this).attr('title')=='unlike'){
    $.post('/like.php',{imid:$(this).attr('id'),action:'unlike'});
     $(this).removeClass('unlike').addClass('like');
     $(this).attr('title','like');
    }
  });
});
</script>
Steven Britton
  • 197
  • 2
  • 5