Toggled boolean variable evaluated in conditional statement on click event - javascript

I am toggling the boolean variable "userTurn". There are two functions that set the value of "userTurn":
runGame(), which sets "userTurn" to true after the last sound in the current round is played.
buttonClick(), which should only be executed if "userTurn" is true. buttonClick sets "userTurn" to false after the user successfully copies the current pattern, or if the user makes a mistake.
I am evaluating the value of "userTurn" in a conditional statement that is inside of a click event.
$(".quarter").on('click', function(){
if( userTurn===true && isOn===true){
var color = $(this).attr('id');
clearTimeout(buzz);
buttonClick(color);
}
})
After the user successfully copies the current pattern, or if the user makes a mistake, "userTurn" is set to false. The problem I am running into is, after "userTurn" is set to false, the code inside the conditional statement is still executing. The goal is for ".quarter" to only be clickable when "userTurn" is true. Why is the buttonClick() function still executing when ".quarter" is clicked even when "userTurn" is false??
Here are the two functions that set the value of "userTurn":
runGame():
function runGame(){
if(isOn===true){
userTurn = false;
count();
playPattern(order, index);
if(index===counter-1&&userTurn===false){
userTurn=true;
clearInterval(play);
buzz = setTimeout(buzzer, 10000);
}else{
index++;
}
} else {
clearInterval(play);
clearTimeout(buzz);
}
}
2.buttonClick():
function buttonClick(color){
var yellowSound = document.getElementById("horseSound");
var redSound = document.getElementById("endFx");
var greenSound = document.getElementById("westernRicochet");
var blueSound = document.getElementById("robotBlip");
$("#red").mousedown(function(){
$("#red").css("background-color", "#ff4d4d");
redSound.play();
});
$("#red").mouseup(function(){
$("#red").css("background-color", "#ff0000");
redSound.pause();
});
$("#blue").mousedown(function(){
$("#blue").css("background-color", "#0000e6");
blueSound.play();
});
$("#blue").mouseup(function(){
$("#blue").css("background-color", "#000099");
blueSound.pause();
});
$("#green").mousedown(function(){
$("#green").css("background-color", "#00e600");
greenSound.play();
});
$("#green").mouseup(function(){
$("#green").css("background-color", "#009900");
greenSound.pause();
});
$("#yellow").mousedown(function(){
$("#yellow").css("background-color", "#ffff4d");
yellowSound.play();
});
$("#yellow").mouseup(function(){
$("#yellow").css("background-color", "#ffff00");
yellowSound.pause();
});
if(color===order[compareIndex]){
userPattern.push(color);
console.log(userPattern, "match");
buzz = setTimeout(buzzer, 10000);
compareIndex++;
if(userPattern.length===counter){
userTurn=false;
compareIndex=0;
index=0;
counter++;
count();
userPattern.length=0;
play = setInterval(runGame, 2000);
clearTimeout(buzz);
}
} else {
userTurn=false;
console.log('don\'t match');
clearTimeout(buzz);
index=0;
compareIndex = 0;
userPattern.length=0;
buzz = setTimeout(buzzer, 1);
}
}
TURN DOWN YOUR VOLUME BEFORE GOING TO THE CODEPEN!!
Here is a link to the codepen.
To start the game click "On Off" and then click "start". The timing is slow so you have to wait for the pattern to play, then click the buttons in the same order as they were played. The problem is seen after the first sound is played. From that point on any click the user makes will play the sound and light up the button, even when the game is playing the pattern and "userTurn" is false. Also be warned, this is still a work in progress, there are a couple of other bugs I'm working on, for example the the first turn the user makes will not light up or play the sound, but the selection is pushed into the correct array and the game will proceed properly based on your selection. I know this is a lot of info but I'm stuck on this so any feed back will be very appreciated. Thanks!

You're using buttonClick to handle clicking the buttons, but inside buttonClick you're setting mouseup and mousedown event listeners for each button as well. Since the individual buttons have their own mouseup and mousedown listeners, the events will happen whether or not buttonClick is called again.
You would have to check if userTurn is true inside of each of those event handlers as well to prevent them from triggering. Also, it would better to set these outside of buttonClick so you won't be adding new listeners every time buttonClick gets called.

Related

JQuery - mousedown,mouseup and click on same element

I have a carousel and I need to make him work as Instagram carousel does.
On click change slide, but on mousedown just stop animation. My JQuery :
$(".fancy-carousel").on('mousedown',function (e) {
...stop animation
});
$(".fancy-carousel").on('mouseup',function (e) {
..continue animation
});
$(".fancy-carousel").on('click',function (e) {
..change slide
});
But i don´t know how can i let script know about difference between "click" and "mousedown". When i click on element and hold for a time, it stop animation but after "mouseup" it trigger "click" event too. Is there any way how to split this events? Or should i do it with some calculating of mouse hold time?
A “click” is just a full cycle of a “mousedown” and a “mouseup”. You can’t have one without the other.
For your code to know the difference, you’ll need a variable that tracks your intentions.
Create a variable to track your intention - default it to “click”.
var intention = "click";
In your mousedown function, pause the animation and start a timer. We will use this timer to detect how long the mouse is down for (I.e, if it’s for over a second, it’s not a click and you just want to trigger mouseup)
var detectIntention = setTimeout(function(){
intention = "mouseup";
})
In your mouse up function, cancel this timeout. If mouse up is called after just a few MS, then you want to do a click.
clearTimeout(detectIntention);
if (intention === "mouseup") {
// do mouseup stuff
}
// reset intention
intention = click;
Check in your click function that you wanted to do a click;
if (intention === "click") {
// do click stuff
}

Call a method once, only if button is clicked (atleast once)

I would like to call loadNext() method only once, if any of the other buttons are clicked at least once.
I have checked out: Calling a Method Once
For example, I am making a quiz app, having question and some options for each question types.
User will select an option and hit on next button to load the next question(with options), (those are predefined in an array). loadNext() shouldn't be called multiple times even if the options are clicked more than once (to prevent this I avoided calling loadNext() inside onclick method of those options(buttons), and also wont load if none of the options are selected,
and my idea is something like pre-defining isClicked as false, and inverting inside onclick method of those options, but that is not working.
What I have done, so far:
var optButtons = $(".opt button");
var isClicked = false;
optButtons.click(function () {
isClicked = true;
console.log("clicked on opt buttons: " + this.id);
console.log("Current button is: " + this.id + " set as active");
//other stuffs
});
//some other stuffs
if (isClicked) {
console.log("Clicked once!");
//other stuffs
loadNext();
} else {
alert("Please select an option");
//browser is alerting very first time after opening `index.html` file
// and Next button click isn't working after that
}
Any instruction will be appreciated, thanks in advance!
I am new in JS.
How about something of the sort, assuming you have an id="next" for your Next button
$("#next").on('click',function(){
if(isClicked){
loadNext();
// Set isClicked to false to reset mechanism
isClicked = false;
}
});
Would this be what you' re looking for ? I understood it this way
you are logging to console when the option buttons are clicked, and that is Ok, but in the onClick listener for the next button, check if the only one option is clicked or not.. and you can create a variable in global scope to check how many
times the next button is clicked, code snippet is
//function called on clicking the next button
function abcd(){
counter++;
if(counter!=-1){
return;
}
else{
//call the loadnext()
}
}
I guess you have your answer with radio buttons. You can try 'radio buttons' for the options. There are enough and more references online. Please let me know if that doesn't suit your requirement.

Vanilla JavaScript - Unbind

I have the following code which looks for a click event for all td elements:
[].forEach.call(document.querySelectorAll('td'), function(e) {
e.addEventListener('click', function(event) {
var clicked = [];
clicked.push(event.target.parentNode.getAttribute('data-a'));
clicked.push(event.target.getAttribute('data-b'));
this.callEvent(clicked, event.target);
}.bind(this));
}.bind(this));
Then I have a basic if else statement that checks the data attrs. It appears like the click function is staying bound as in the if statement I have logged to the console which condition is true.
After the very first run through, the true condition only runs, then if the next run through, the false runs, the true does also.. and then each time after, the conditions runs for each of the previous clicks.
What am I doing wrong? Do I need to somehow unbind the click function each time?

How can I stop triggering click event after the first trigger?

Using a triggered click on my website (Its not on the website not due to the bug).
Website: 3six-d.co.uk
setTimeout(function() {
$('a[href$="#about"]').trigger('click');
}, 5000);
However as you could possible guess, that works fine. Until someone click the Enter button faster than 5 seconds, and they goes to a different tab. Say I clicked enter then went to the contact form. After the 5 seconds it would then redirect me back to about us. If there a way that if the user has already clicked enter it stops the trigger?
Thanks
You can try this
var isClicked = false;
setTimeout(function() {
if (!isClicked) {
isClicked = true;
$('a[href$="#about"]').trigger('click');
}
}, 5000);
With the former approach you guarantee that the click is only triggered once. No matter how often the user clicks.
How about a global Boolean variable that is set to true once the trigger is clicked? If the global Boolean is true, it does not allow the trigger event to run again. And, when the global is set to true, another timer is started that resets it to false after five or six seconds?
Detect when a user click the "Enter" button (look this up, its easy) then clear the timeouts using:
var id = window.setTimeout(function() {}, 0);
while (id--) {
window.clearTimeout(id);
}

Unwanted sound loop JavaScript

setInterval(collector, 1000/FPS);
This calls the collector, that runs the following:
function collector(){
inputinterval();
draw();
soundplay();
//DEBUG FEATURES BELOW
//console.log(mousepos);
//console.log(mousedrag);
}
In inputinterval there is code that determines whether the user is dragging something or not. By default he is, but by pressing the spacebar it drops the element from the mouse pointer. Now this would be fun to have sound, so I did the following to test the sound:
//SOUND
//function soundplay(){
// if (!(mousedrag)){
// snd_putdown.play();
// };
//};
I've commented it out for now because it's looping even when no mouse button is pressed.
The mousedrag is determined in an input function:
if (event.keyCode == 65) {
mousedrag = true;
}
if (event.keyCode == 83) {
mousedrag = false;
}
Currently replaced by keyboard inputs since my mousebuttons aren't working either. This bit of code is part of inputinterval() that is called in the collector, that is called by the setInterval function. That causes tremendous looping. How would I go about doing the sound so that is not part of the loop, but does respond to the user dropping something (and picking it back up > dropping> etc...).
Thanks in advance!
EDIT: Well, I skipped the whole dropping of parts for now and choose to alter the design rather than breaking my head over such thing. I'd still like to know how to do this, but for now it can do without. The progress can be seen here, along with the source and what not: koewaffle.koding.com/pcgametest/index.html .

Categories

Resources