I’m trying to create a Simon Game and when the user click the button I want it to be animated.
I used addClass and setTimeOut with removeClass, the animation happens but I need to click the same button two times.
var buttonColours = ["red", "blue", "green", "yellow"];
var gamePattern = [];
var userClickedPattern = [];
function playSound(name) {
var audio = new Audio("./sounds/" + name + ".mp3");
audio.play();
}
function nextSequence() {
var randomNumber = Math.floor(Math.random() * 4);
var randomChosenColour = buttonColours[randomNumber];
gamePattern.push(randomChosenColour);
$("#" + randomChosenColour).fadeOut(100).fadeIn(100);
playSound(randomChosenColour);
}
function animatePress(currentColour) {
$("." + currentColour).on("click", function () {
$("." + currentColour).addClass("pressed");
setTimeout(function () {
$("." + currentColour).removeClass("pressed");
}, 100);
})
}
$(".btn").on("click", function () {
var userChosenColour = this.id;
userClickedPattern.push(userChosenColour);
playSound(userChosenColour);
animatePress(userChosenColour);
})
2
Answers
Seems like you have attached the click event handler inside the animatePress function each time the button is clicked, causing it to require two clicks on subsequent attempts.
Please separate the click handler from the animatePress function,
Hope this helps!
The short answer was given by @santhoshprem but if you would like to better understand your problem and the solution here is the long answer…
The nested event handlers in the animatePress function prevent the second click event from firing. This is because the animatePress function creates a new click event handler that is encapsulated within it.
Understanding the Problem
Encapsulated event handler
The first click of the button executes the click handler as follows :
Lets call this "first click". Now with that click event fired(first click), it calls the
animatePress()
function which then creates another click event handler that needs a click itself(second click) to execute the.addClass()
and.removeClass()
methods. This new click event handler is encapsulated insideanimatePress()
, meaning it’s inaccessable outside ofanimatePress()
.Normally these handlers could fire as one on the stack but becuase the second handler can’t be accessed until the first handler calls
animatePress()
. They get separated on the stack.It goes something like this…
The second event handler(inside
animatePress()
) is not created until after the first event handler is fired and done.Understanding the solution
Less is more?
To solve your problem simply remove
$("." + currentColour).on("click", function () { }
from theanimatedPress()
function like this :Now there’s only one click event needed to complete execution.
Complete corrected code
Expectation vs Reality
If both event handlers where created and executed at the same time you could fire both events with 1 click. But that’s not the case nor is it necessary in this case. This might be a little excessive of an answer but hopefully is helps you understand and prepare for future situations.
Happy Dev-Ops!
-Tekk