How Can I Get The mousedown Condition In for loop? - javascript

I want to get the mousedown condition in for loop.
But I cannot get it even if I mousedown trigger element(ex:#mousedown_button).
How can I get mousedown condition after starting for loop?
$("#mousedown_button").mousedown(function() {
for_loop()
});
function for_loop() {
for (i = 50; i > 0; i--) {
// I cannot get the count_flag(always false even if I mousedown #mousedown_button)
count_flag = get_mousedown_condition();
if (count_flag == false) {
break;
}
console.log(i);
var start = new Date();
while ((new Date() - start) < 250);
}
}
function get_mousedown_condition() {
// get the count flag
$("#mousedown_button").mouseover(function() {
return false;
}).mouseleave(function() {
return false;
}).mousedown(function() {
return true
}).mouseup(function() {
return false;
});
return false;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<div id='mousedown_button'>Click</div>

the way you tried, you bind all the event-handlers like 50 times and their return value will never enter your desired scope, because i am not sure what you try - i just leave this as an answer how you could store your "count_flag" and retrieve it in your loop
var count_flag = false;
function for_loop() {
for (i = 50; i > 0; i--) {
if (count_flag == false) {
break;
}
console.log(i);
var start = new Date();
while ((new Date() - start) < 250);
}
}
function set_mousedown_condition {
$("#mousedown_button").mouseover(function() {
count_flag = false;
}).mouseleave(function() {
count_flag = false;
}).mousedown(function() {
count_flag = true;
for_loop(); // start the loop also here instead of override the binding
}).mouseup(function() {
count_flag = false;
});
}
// initialize everything once
set_mousedown_condition()

Related

Setting interval only once by an event listener, but run other functions every time

See this code:
function handleTouchStart(event) {
event.preventDefault();
cnvs.removeEventListener("touchstart", handleTouchStart);
var x1 = event.touches[0].clientX-cnvs.offsetLeft;
callerOfCNVSTouchStart = setInterval(function () {
if (x1 > cnvs.width/2 && whiteShip.x2 < cnvs.width) {
whiteShip.x1+= 3;
} else if (x1 < cnvs.width/2 && whiteShip.x1 > 0) {
whiteShip.x1-= 3;
}
}, 20);
nBMC = setInterval(makeNewBullets,200);
setInterval(sendEnemies,2000);//I want to run this line only once
}
I want the other functions to run every time the event occurs, but set the interval for sendEnemies only once. How can I do that?
Use a variable like var sentEnemies = false; outside function handleTouchStart and update it in the function to true the first time and use if(!sentEnemies) for the line to execute only once.
var sentEnemies = false;
function handleTouchStart(event) {
event.preventDefault();
cnvs.removeEventListener("touchstart", handleTouchStart);
var x1 = event.touches[0].clientX-cnvs.offsetLeft;
callerOfCNVSTouchStart = setInterval(function () {
if (x1 > cnvs.width/2 && whiteShip.x2 < cnvs.width) {
whiteShip.x1+= 3;
} else if (x1 < cnvs.width/2 && whiteShip.x1 > 0) {
whiteShip.x1-= 3;
}
}, 20);
nBMC = setInterval(makeNewBullets,200);
if (!sentEnemies) {
setInterval(sendEnemies,2000); // Will execute only once
sentEnemies = true;
}
}

How do I stop a while loop with a button - JavaScript

Hello guys I'm looking for a solution for this program:
var i = 0;
function timer(milliseconds) {
var start = new Date().getTime();
for (var i = 0; i < 1e7; i++) {
if ((new Date().getTime() - start) > milliseconds) {
break;
}
}
}
$w.onReady(function () {
while (i === 0) {
dosomething();
timer(1000);
}
});
export function button5_click(event) {
i = 1;
}
My question is how can I stop this while with that button function?
You can do this way!
var flag = true;
let i = 0;
function loopFunc() {
if (flag == true){
i++;
console.log( `Do something here ${i}` );
setTimeout(loopFunc, 100);
}
}
loopFunc();
function stop(){
flag = false;
}
<button onclick="stop();">Stop Loop</button>
You could have a boolean which is checked if true in the while loop and if it true, the while loop will return. Add in an event listener to make that boolean true on click for the button. Don't forget to make the boolean false at the beginning of your script.
Using your code, you could do this
var stopLoop = false; // Add this to your code
var i = 0;
function timer(milliseconds) {
var start = new Date().getTime();
for (var i = 0; i < 1e7; i++) {
if ((new Date().getTime() - start) > milliseconds) {
break;
}
}
}
$w.onReady(function () {
while (i === 0) {
if(stopLoop) break;
dosomething();
timer(1000);
}
});
export function button5_click(event) {
stopLoop = true; // add this to your code
i = 1; // You can comment this out
}

jQuery Memory Skill game setTimeout() issues

I am making a little game of Simon with jQuery. I have the functionality I want; start on page load, score, round numbers, etc, and the game works to an extent.
However, I still have a problem that I can't get my head around. I want to be able to prevent the user from being able to select the panels during the computer's turn. Currently, the user can trigger a sequence during the computer displaying its output, which causes havoc with buttons flashing and sounds going off.
The issue lies in setTimeout(). I tried to implement a variable 'cpuLoop' which turns to true when it's the computer's turn, and then back to false, but the implementation of setTimeout() means that there are still events on the event loop even after cpuLoop has been changed to false. The change to false changes immediately when of course it should wait until the setTimeout() has completed.
A similar problem is encountered when the reset button is clicked. When clicked, it should interrupt the setTimeout() events and restart the game. As it is, it continues outputting the computer's turn.
To get around this, I have attached the setTimeout() functions in the global scope and attempted to cut them off with clearInterval(var) but this seems to have no effect at the moment.
Here is my jQuery:
$(function(){
var counter = 0;
var cpuArray = [];
var cpuSlice = [];
var numArray = [];
var userArray = [];
var num = 1;
var wins = 0;
var losses = 0;
var cpuLoop = false;
// Initialise the game
function init(){
$('#roundNumber').html('1');
counter = 0;
cpuArray = [];
numArray = [];
userArray = [];
cpuLoop = false;
num = 1;
// Create cpuArray
function generateRandomNum(min, max){
return Math.floor(Math.random() * (max - min) + min);
}
for(var i = 1; i <= 20; i++){
numArray.push(generateRandomNum(0, 4));
}
for(var i = 0; i < numArray.length; i++){
switch(numArray[i]){
case 0:
cpuArray.push('a');
break;
case 1:
cpuArray.push('b');
break;
case 2:
cpuArray.push('c');
break;
case 3:
cpuArray.push('d');
break;
}
}
console.log('cpuArray: ' + cpuArray);
// Create a subset of the array for comparing the user's choices
cpuSlice = cpuArray.slice(0, num);
goUpToPoint(cpuSlice);
}
init();
var looperA, looperB, looperC, looperD;
// Cpu plays sounds and lights up depending on cpuArray
function cpuPlayList(input, time){
setTimeout(function(){
if(input === 'a'){
looperA = setTimeout(function(){
aSoundCpu.play();
$('#a').fadeOut(1).fadeIn(500);
}, time * 500);
} else if(input === 'b'){
looperB = setTimeout(function(){
bSoundCpu.play();
$('#b').fadeOut(1).fadeIn(500);
}, time * 500);
} else if(input === 'c'){
looperC = setTimeout(function(){
cSoundCpu.play();
$('#c').fadeOut(1).fadeIn(500);
}, time * 500);
} else if(input === 'd'){
looperD = setTimeout(function(){
dSoundCpu.play();
$('#d').fadeOut(1).fadeIn(500);
}, time * 500);
}
}, 1750);
};
// CPU takes its turn
function goUpToPoint(arr){
cpuLoop = true;
console.log('cpuLoop: ' + cpuLoop);
for(var i = 0; i < arr.length; i++){
cpuPlayList(arr[i], i);
}
cpuLoop = false;
console.log('cpuLoop: ' + cpuLoop);
}
// User presses restart button
$('.btn-warning').click(function(){
clearTimeout(looperA);
clearTimeout(looperB);
clearTimeout(looperC);
clearTimeout(looperD);
init();
});
// Array comparison helper
Array.prototype.equals = function (array) {
// if the other array is a falsy value, return
if (!array)
return false;
// compare lengths - can save a lot of time
if (this.length != array.length)
return false;
for (var i = 0, l=this.length; i < l; i++) {
// Check if we have nested arrays
if (this[i] instanceof Array && array[i] instanceof Array) {
// recurse into the nested arrays
if (!this[i].equals(array[i]))
return false;
}
else if (this[i] != array[i]) {
// Warning - two different object instances will never be equal: {x:20} != {x:20}
return false;
}
}
return true;
}
// User presses one of the four main buttons
function buttonPress(val){
console.log('strict?: ' + $('#strict').prop('checked'));
console.log('cpuSlice: ' + cpuSlice);
userArray.push(val);
console.log('userArray: ' + userArray);
if(val === 'a'){ aSoundCpu.play(); }
if(val === 'b'){ bSoundCpu.play(); }
if(val === 'c'){ cSoundCpu.play(); }
if(val === 'd'){ dSoundCpu.play(); }
// If the user selected an incorrect option
if(val !== cpuSlice[counter])
//Strict mode off
if(!$('#strict').prop('checked')){
// Strict mode off
alert('WRONG! I\'ll show you again...');
userArray = [];
console.log('cpuSlice: ' + cpuSlice);
goUpToPoint(cpuSlice);
counter = 0;
} else {
//Strict mode on
losses++;
$('#lossCount').html(losses);
ui_alert('You lose! New Game?');
return;
} else {
// User guessed correctly
counter++;
}
if(counter === cpuSlice.length){
$('#roundNumber').html(counter + 1);
}
if(counter === 5){
ui_alert('YOU WIN!');
$('#winCount').html(++wins);
return;
}
console.log('counter: ' + counter);
if(counter === cpuSlice.length){
console.log('num: ' + num);
cpuSlice = cpuArray.slice(0, ++num);
console.log('userArray:' + userArray);
userArray = [];
console.log('cpuSlice: ' + cpuSlice);
goUpToPoint(cpuSlice);
counter = 0;
}
}
// Button presses
$('#a').mousedown(function(){
if(!cpuLoop){
buttonPress('a');
}
});
$('#b').mousedown(function(){
if(!cpuLoop) {
buttonPress('b');
}
});
$('#c').mousedown(function(){
if(!cpuLoop){
buttonPress('c');
}
});
$('#d').mousedown(function(){
if(!cpuLoop){
buttonPress('d');
}
});
// jQuery-UI alert for when the user has either won or lost
function ui_alert(output_msg) {
$("<div></div>").html(output_msg).dialog({
height: 150,
width: 240,
resizable: false,
modal: true,
position: { my: "top", at: "center", of: window },
buttons: [
{
text: "Ok",
click: function () {
$(this).dialog("close");
init();
}
}
]
});
}
// Sound links
var aSoundCpu = new Howl({
urls: ['https://s3.amazonaws.com/freecodecamp/simonSound1.mp3'],
loop: false
});
var bSoundCpu = new Howl({
urls: ['https://s3.amazonaws.com/freecodecamp/simonSound2.mp3'],
loop: false
});
var cSoundCpu = new Howl({
urls: ['https://s3.amazonaws.com/freecodecamp/simonSound3.mp3'],
loop: false
});
var dSoundCpu = new Howl({
urls: ['https://s3.amazonaws.com/freecodecamp/simonSound4.mp3'],
loop: false
});
});
and here is a link to the app on codepen. Many thanks
This seemed to work OK for me for disabling user input during the computer's turn:
function goUpToPoint(arr){
cpuLoop = true;
console.log('cpuLoop: ' + cpuLoop);
for(var i = 0; i < arr.length; i++){
cpuPlayList(arr[i], i);
}
//cpuLoop = false;
setTimeout(function() {
cpuLoop = false;
}, arr.length * 500 + 1750);
console.log('cpuLoop: ' + cpuLoop);
}
Then for the reset button, put this with your globals above function init()
timeoutsArray = [];
and make these function edits:
// Cpu plays sounds and lights up depending on cpuArray
function cpuPlayList(input, time){
timeoutsArray.push(setTimeout(function(){
if(input === 'a'){
timeoutsArray.push(setTimeout(function(){
aSoundCpu.play();
$('#a').fadeOut(1).fadeIn(500);
}, time * 500));
} else if(input === 'b'){
timeoutsArray.push(setTimeout(function(){
bSoundCpu.play();
$('#b').fadeOut(1).fadeIn(500);
}, time * 500));
} else if(input === 'c'){
timeoutsArray.push(setTimeout(function(){
cSoundCpu.play();
$('#c').fadeOut(1).fadeIn(500);
}, time * 500));
} else if(input === 'd'){
timeoutsArray.push(setTimeout(function(){
dSoundCpu.play();
$('#d').fadeOut(1).fadeIn(500);
}, time * 500));
}
}, 1750));
};
// User presses restart button
$('.btn-warning').click(function(){
for(var i = 0; i < timeoutsArray.length; i++) {
clearTimeout(timeoutsArray[i]);
}
timeoutsArray = [];
init();
});
I think you were replacing some of your looperX variable values. Using an array to store all of your setTimeout functions guarantees that they all get cleared.
Your problem is that setTimeout is an asynchronous function, which means that once you called it, the code after it continue as if it is done.
If you want the code to wait until the end of your loop, you need to invoke it at the end of the setTimeout function.
You could split your function in two (in your case it's the goUpToPoint function), something like this:
function first_part() {
//Call setTimeout
setTimeout(function() { some_function(); }, time);
}
function second_part() {
// Rest of code...
}
function some_function() {
//Delayed code...
...
second_part();
}
Since you are calling your function a number of times, I would create a global counter that you can decrease at the end of each setTimeout call, and call the second_part function only if the counter is 0:
var global_counter = 0;
function first(num) {
//Call setTimeout
global_counter = num;
for (var i = 0; i < num; i++) {
setTimeout(function() { some_function(); }, time);
}
}
function second() {
// Rest of code...
}
function some_function() {
//Delayed code...
...
// Decrease counter
global_counter--;
if (global_counter == 0) {
second();
}
}

Javascript - Check if key was pressed twice within 5 secs

I want to check if Enter key was pressed twice within 5 secs and perform some action.
How can I check if the key was pressed once or twice within a given time and perform different actions.
Here is my code:
<h1 id="log">0</h1>
<br/>
<span id="enteredTime">0</span>
<script>
$(document).keypress(function(e) {
if(e.which == 13){
var element = $("#log");
var timeDifference = 0;
//Log the timestamp after pressing Enter
$("#enteredTime").text(new Date().getTime());
//Check if enter was pressed earlier
if ($("#enteredTime").text() !== "0") {
var now = new Date().getTime();
var previous = $("#enteredTime").text();
difference = now - previous;
}
//Check if enter was pressed only once within 5 secs or more
if(){
$("#log").text("Once");
$("#enteredTime").text("0");
//Check if enter was pressed twice in 5 secs
}else{
$("#log").text("Twice in less than 5 secs");
$("#enteredTime").text("0");
}
}
});
</script>
http://jsfiddle.net/Rjr4g/
Thanks!
something like
var start=0;
$(document).keyup(function(e) {
if(e.keyCode == 13) {
elapsed = new Date().getTime();
if(elapsed-start<=5000){
//do something;
}
else{
//do something else;
}
start=elapsed;
}
});
Try a timer based solution like
var flag = false,
timer;
$(document).keypress(function (e) {
var element = $("#log");
var timeDifference = 0;
if (e.which == 13) {
if (flag) {
console.log('second');
clearTimeout(timer);
flag = false;
} else {
console.log('first');
flag = true;
timer = setTimeout(function () {
flag = false;
console.log('timeout')
}, 5000);
}
//Log the timestamp after pressing Enter
$("#enteredTime").text(new Date().getTime());
if ($("#enteredTime").text() !== "0") {
var now = new Date().getTime();
var previous = $("#enteredTime").text();
difference = now - previous;
}
}
});
Demo: Fiddle
Bacon.js seems like a good tool to express this.
$(document).asEventStream('keypress')
.filter(function (x) {
return x.keyCode == 13;
})
.map(function () {
return new Date().getTime();
})
.slidingWindow(2, 1)
.map(function (x) {
return (x.length == 1 || x[1] - x[0] > 5000) ? 1 : 2;
})
.onValue(function (x) {
$("#log").text(x == 1 ? "Once" : "Twice in less than 5 secs");
});
(fiddle)
here is my solutions, please check it if match your idea :)
(function($){
var element = $("#log");
var timeDifference = 0;
var count = 0;
$(document).keypress(function(e) {
if(e.which === 13){
//do what you want when enterpress 1st time
/*blah blah */
//after done 1st click
count++;
if(count === 2) {
//do what you want when enterpress 2nd time in 5 seconds
/* blah blah */
//after done
clearTimeout(watcher);
count = 0;
return;
}
//setTimeout to reset count if more than 5 seconds.
var watcher = setTimeout( function() {
count = 0;
},5000);
}
});
}(jQuery)
Check your Updated Fiddle
var count = 0;
$(document).keypress(function(e) {
var element = $("#log");
var timeDifference = 0;
if(e.which == 13){
count++;
console.log('enter pressed'+count);
if(count == 1){
startTimer();
}
else{
checkCount();
}
//Log the timestamp after pressing Enter
$("#enteredTime").text(new Date().getTime());
if ($("#enteredTime").text() !== "0") {
var now = new Date().getTime();
var previous = $("#enteredTime").text();
difference = now - previous;
}
}
});
function startTimer(){
setTimeout(checkCount,5000);
}
function checkCount(){
if(count == 1){
$("#log").text("Once");
$("#enteredTime").text("0");
//Check if enter was pressed twice in 5 secs
}else{
$("#log").text("Twice in less than 5 secs");
$("#enteredTime").text("0");
}
}
startTimer() starts counting on first enter press. And checkCount() contains your condition after 5secs.
setTimeout() lets you attach an event which occurs after a specific timespan.

clearInterval is not clearing

Take a look at the function below, It purpose is to change the button text
to "Abort", "Abort 0", "Abort 1" and so on.
Once the counter reaches 10 another function should be executed, but if
the button is clicked, the counter should stop, and the button text should return
to it's original value ("Sync DB").
It seems I'm trying to clear out the interval in a wrong way.
Any assistance will be appreciated.
function sync_database(abort)
{
if (abort == true) { sync_db_btn.innerHTML = "Sync DB"; return false }
sync_db_btn.innerHTML = "Abort"
var i = 0;
sync_db_btn.addEventListener("click", function() { sync_database(true) } );
var x = setInterval(function() {
if (abort == true) {
clearInterval(x);
}
if (i < 10) {
sync_db_btn.innerHTML = "Abort " + i++;
}
}, 1000);
}
var x;
sync_db_btn.addEventListener("click", function() {
sync_database(true);
clearInterval(x);
} );
function sync_database(abort)
{
if (abort == true) { sync_db_btn.innerHTML = "Sync DB"; return false }
sync_db_btn.innerHTML = "Abort"
var i = 0;
x = setInterval(function() {
if (i < 10) {
sync_db_btn.innerHTML = "Abort " + i++;
}
}, 1000);
}
I think you need something like this:
var sync_db_btn = document.getElementById('but'),
abortSync = -1,
interval,
sync_database = function () {
var i = 0;
abortSync *= -1;
if (abortSync < 0) {
sync_db_btn.innerHTML = 'Sync DB';
clearInterval(interval);
return false;
}
sync_db_btn.innerHTML = 'Abort';
interval = setInterval(function () {
if (i < 10) {
sync_db_btn.innerHTML = 'Abort ' + i++;
} else {
sync_db_btn.innerHTML = 'Sync DB';
clearInterval(interval);
abortSync = -1;
}
}, 1000);
};
sync_db_btn.addEventListener('click', sync_database);
A live demo at jsFiddle.

Categories