1

I have a like button, when you press the button it is supposed to change state. Im doing it with jQuery. When you click the button it changes color's and in ctrl+shift+i also classes however it doesnt change classes in ctrl+u+i which causes jQuery to not notice the change of classes. Essentialy the first time you click the button it will change color but than it will be static. Any idea how to fix it?

Here is my code:

$('.unclicked-like-button').click(function(){ 
    $(this).removeClass('unclicked-like-button'); 
    $(this).addClass('clicked-like-button');
})

$('.clicked-like-button').click(function(){ 
    $(this).removeClass('clicked-like-button'); 
    $(this).addClass('unclicked-like-button');
})
.unclicked-like-button {
color: black;
}
            
.clicked-like-button {
color: blue;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>

<button class = 'unclicked-like-button' id='like-button'> Like </button>
A. Meshu
  • 4,053
  • 2
  • 20
  • 34

2 Answers2

1

The problem is that you are attaching the listeners to the elements which have the classes unclicked-like-button and clicked-like-button at the point of attachment - ie when the page first loads. At that point, there is one button with the first class, and none with the second class. Although after the first click, the event handler changes the class, that doesn't change which event handler function is attached to the click of the button. That handler was attached to the element itself, not to any element that may or may not later have that class.

While you can solve this with event delegation, as @evolutionxbox mentioned in his comment, the most straightforward way here is I think just to attach the handler using the button's ID - to be unambiguous to anyone reading the code about which element is receiving it - and then check for the current class inside the handler:

$('#like-button').click(function(){
    if ($(this).hasClass('unclicked-like-button') {
        $(this).removeClass('unclicked-like-button'); 
        $(this).addClass('clicked-like-button');
    } else {
        $(this).removeClass('clicked-like-button'); 
        $(this).addClass('unclicked-like-button');
    }
})
Robin Zigmond
  • 17,805
  • 2
  • 23
  • 34
1

Since the javascript runs when the page loads, it can only find the unclicked-like-button. I moved this into a function to run every time the button is clicked and it seems to have solved your issue.

<script src="https://code.jquery.com/jquery-3.4.1.js" integrity="sha256-WpOohJOqMqqyKL9FccASB9O0KwACQJpFTUBLTYOVvVU=" crossorigin="anonymous">
</script>
<style>
.unclicked-like-button {
color: black;
}
            
.clicked-like-button {
color: blue;
}
</style>

<button class='unclicked-like-button' id='like-button' onclick="changeState()">Like</button>

<script type="text/javascript"> 

function changeState() {
    const likeButton = $('#like-button');
    if (likeButton.hasClass('unclicked-like-button')) {
        likeButton.removeClass('unclicked-like-button'); 
        likeButton.addClass('clicked-like-button');
    } else {
        likeButton.removeClass('clicked-like-button'); 
        likeButton.addClass('unclicked-like-button');
    }   
}
</script>
  • This is great, Thank you very much. I have been looking for a solution all day. The only problem is that the first click doesnt affect it, only after the second click it starts taking affect. Other than calling the function twice is there a easy way to fix this problem? – bookim online Aug 11 '21 at 20:49
  • Hmm strange. Let me take another look at this. – Will Franklyn Aug 11 '21 at 21:04
  • Okay I simplified the function down a bit and got it working properly: function changeState() { const likeButton = $('#like-button'); if (likeButton.hasClass('unclicked-like-button')) { likeButton.removeClass('unclicked-like-button'); likeButton.addClass('clicked-like-button'); } else { likeButton.removeClass('clicked-like-button'); likeButton.addClass('unclicked-like-button'); } } – Will Franklyn Aug 11 '21 at 21:10
  • I'll edit my previous answer. – Will Franklyn Aug 11 '21 at 21:10
  • Why does this fix the problem? – bookim online Aug 11 '21 at 21:16
  • Before we were still waiting for a second click after the first one. The function would get called but inside of the function we were looking for $(this).click. Now we know that the button has been clicked so we just swap the classes. – Will Franklyn Aug 11 '21 at 22:29
  • 1
    Thank you very much, your help is most appreciated – bookim online Aug 11 '21 at 22:55