Reputation: 3692
I'm making a Twitch Streamer application, that pulls some data using Twitch API, for a predetermined set of streamers.
I have three buttons to select all/online/offline channels, and I am looking to add the animated shake
effect to all these buttons.
On my first attempt, I had a simple if/else check in place to make the shake
work correctly - detect if the animated shake
class already exists, if so, remove it, and then add it again. Else, just add it.
That didn't work. I found an answer here on SO that said it won't work that way because the addClass
and removeClass
occur so fast that the DOM doesn't have time to catch up.
I then used a queue
with an anonymous function to add the class back after inducing a slight delay after the removeClass
-
if ($(this).hasClass("animated shake")) {
$(this).removeClass("animated shake").delay(50).queue(
function() {
$(this).addClass("animated shake");
});
//$(this).addClass("animated shake");
} else {
$(this).addClass("animated shake");
}
Now, the shake effect works like 90% of the time, but if you keep switching back and forth between online/offline channels, there will be cases in between where the shake doesn't work.
Here's the app on Codepen.
I'd appreciate any help as to why it doesn't work every single time.
Note - The shake effect is on the online/offline buttons only, for now.
Upvotes: 0
Views: 1445
Reputation: 5099
This works everytime :-D
function shakeButton($button) {
console.log('Shaking button')
$button.removeClass("animated shake");
setTimeout(
function() {
$button.addClass("animated shake");
},
25
);
}
$('button').click(function() {
shakeButton($(this));
});
<!-- Never mind, Just some Dummy html... -->
<link href="https://cdnjs.cloudflare.com/ajax/libs/animate.css/3.5.1/animate.min.css" rel="stylesheet" />
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<h4>Never mind this, Just some Dummy Results</h4>
<h3>Check out the JS instead</h3>
<button>Button 1</button>
<button>Button 2</button>
<button>Button 3</button>
I just used setTimeout instead .delay()
And it worked a treat :-)
Good Job, Your code is nice and well documented :-D A Few things though...
if
statement you use is not necessary... Just remove animate
and shake
classes every time ( it won't throw any error ;-) ) and add them after some time again, this will make code simpler.This code is implemented in this snippet... http://codepen.io/shramee/pen/EyZJjN
Upvotes: 2
Reputation: 5546
can you try something like this?
$('.btn').on('click', function()
{
// Siblings will target other buttons but not the current one
$(this).addClass('animated shake').siblings().removeClass('animated shake');
});
[EDIT] more relevent to your structure:
According to your example structure you can add a class to your buttons wrapper like .btnWrapper
for convenience and do:
$('.btn').on('click', function()
{
var clicked = $(this);
clicked.addClass('animated shake').parents('.btnWrapper').siblings().find('.shake').removeClass('animated shake');
})
Upvotes: 1