clearTimeout() inside setTimeout() method not working in JS - javascript

clearTimeout() inside setTimeout() method not working in JavaScript
var c = 0;
var t;
function timedCount() {
document.getElementById('txt').value = c;
c = c + 1;
if (c == 5) {
clearTimeout(t);
}
t = setTimeout(function () {
timedCount()
}, 1000);
}
jsFiddle

You need to prevent the rest of the code of executing, actually you are re-declaring t after clearing the setTimeout. Fiddle
var c = 0;
var t;
function timedCount() {
document.getElementById('txt').value = c;
c = c + 1;
if (c == 5) {
clearTimeout(t);
return false;
}
t = setTimeout(timedCount, 1000);
}
Or just use the else statement:
if (c == 5) {
clearTimeout(t);
// do something else
}else{
t = setTimeout(timedCount, 1000);
}

There will never be a timeout to clear when you call clearTimeout as the last one will have already fired and the next one won't have been set yet.
You want to change your logic so that if (c !== 5) { setTimeout(etc etc) }

Related

Stop recursive setTimeout function

Im running a recursive setTimeout function and I can run it many times, it has a clearTimeout, with this property I can handle how to stop the function running.
But I can't figure out how to stop it in another function.
var a = 0;
var b = 0;
function Listener(x, y) {
var lValue = y == true ? a : b;
if (lValue < 100) {
console.log(lValue);
if(y == true){
a+=x;
}else{
b+=x;
}
setTimeout(Listener.bind(this, x, y), 1000);
} else {
clearTimeout(Listener);
if(y == true){
a=0;
}else{
b=0;
}
}
}
When i tried to run it twice, it works:
My doubt is: How can I stop a particular running instance.
A couple notes:
Given the constant timeout of 1000, you should be using setInterval() instead. It will greatly simplify your function, and allow you to cancel the interval whenever you want.
Using global variables is code smell, create an object instead to hold a reference to the value being incremented. Doing so will also allow your function parameters to be more intuitive.
Here's a solution incorporating these two suggestions:
function range (step, start = 0, stop = 100) {
const state = {
value: start,
interval: setInterval(callback, 1000)
};
function callback () {
if (state.value < stop) {
console.log(state.value);
state.value += step;
} else {
console.log('timer done');
clearInterval(state.interval);
}
}
callback();
return state;
}
const timer1 = range(10);
const timer2 = range(20);
setTimeout(() => {
console.log('stopping timer 1');
clearInterval(timer1.interval);
}, 2500);
setTimeout(() => {
console.log('timer 2 value:', timer2.value);
}, 3500);
You could elevate the timer to a higher scope that is accessible by other functions.
var a = 0;
var b = 0;
var timer = null;
function Listener(x, y) {
var lValue = y == true ? a : b;
if (lValue < 100) {
console.log(lValue);
if (y == true) {
a += x;
} else {
b += x;
}
timer = setTimeout(Listener.bind(this, x, y), 1000);
} else {
clearTimeout(timer);
if (y == true) {
a = 0;
} else {
b = 0;
}
}
}
function clearTimer() {
if (timer !== null) clearTimeout(timer);
}
Listener(3, 3);
// clear the timer after 3 secnods
setTimeout(clearTimer, 3000);
create a variable and store the reference of setTimout on that variable, after that you just clearTimout with that variable reference
e.x
GLOBAL VARIABLE:
var k = setTimeout(() => { alert(1)}, 10000)
clearTimeout(k)
var a = 0;
var b = 0;
var recursiveFunctionTimeout = null;
function Listener(x, y) {
var lValue = y == true ? a : b;
if (lValue < 100) {
console.log(lValue);
if(y == true){
a+=x;
}else{
b+=x;
}
recursiveFunctionTimeout = setTimeout(Listener.bind(this, x, y), 10);
} else {
clearTimeout(recursiveFunctionTimeout);
if(y == true){
a=0;
}else{
b=0;
}
}
}
LOCAL VARIABLE:
var a = 0;
var b = 0;
function Listener(x, y) {
var lValue = y == true ? a : b;
var recursiveFunctionTimeout = null;
if (lValue < 100) {
console.log(lValue);
if(y == true){
a+=x;
}else{
b+=x;
}
recursiveFunctionTimeout = setTimeout(Listener.bind(this, x, y), 10);
} else {
clearTimeout(recursiveFunctionTimeout);
if(y == true){
a=0;
}else{
b=0;
}
}
}

Why can't I clear this timer in JavaScript?

There is an object.
There is this method that initializes the timer in another method within the same object.
initstep1() {
var totAns = TriviaGame.corAnswered + TriviaGame.incorAnswered;
//for (let v=0;v<TriviaGame.arrayOfSelected.length;v++){TriviaGame.arrayOfSelected.pop();}
//for (let u=0;u<TriviaGame.arrayOfIntervals.length;u++){clearInterval(TriviaGame.arrayOfIntervals[u]);TriviaGame.arrayOfIntervals.pop();}
$("#maincontact0").css("display", "none");
$("#maincontact2").css("display", "none");
$("#maincontact1").css("display", "flex");
if (totAns != 10) {
TriviaGame.populatePromptContent();
} else {
TriviaGame.initstep3();
}
if (TriviaGame.corAnswered == 0 && TriviaGame.incorAnswered == 0) {
TriviaGame.giveQuestionsClickEvents();
TriviaGame.giveAnswersClickEvents();
}
$("#maincontact1qr").text() == 30;
TriviaGame.timerOnTheRight();
}
It's called timerOnTheRight...
Here it is...
Never gets cleared no matter what I do.
timerOnTheRight() {
//for (let u=0;u<TriviaGame.arrayOfIntervals.length;u++){clearInterval(TriviaGame.arrayOfIntervals[u]);TriviaGame.arrayOfIntervals.pop();}
console.log(TriviaGame.arrayOfIntervals);
let countDown1 = 30;
var thisVeryTimer = setInterval(function() {
countDown1--;
if ($("#maincontact1qr").text() != 1) {
$("#maincontact1qr").text(countDown1);
}
if ($("#maincontact1qr").text() < 11) {
$("#maincontact1qr").css("color", "orange");
}
if ($("#maincontact1qr").text() < 4) {
$("#maincontact1qr").css("color", "red");
}
if ($("#maincontact1qr").text() == 1) {
TriviaGame.arrayOfCurrent[0].timespent = "Yes";
clearInterval(thisVeryTimer);
TriviaGame.initstep2();
}
}, 600);
}
Make sure the conditional is correct, and the inside the conditional block is working when conditioning is met. You should console out thisVeryTimer to make sure it is the same interval id.
Another issue should be the scope of the variable.
clearInterval(thisVeryTimer);
Try to move the above code out of the interval block.

if statement of button found

My goal is, if a page contains the specified button, click it, and increase the amt_clicked by 1. When amt_clicked is greater than 15, wait for 60 seconds and reset amt_clicked. I have no idea how do this if statement. Example:
var amt_clicked = 0;
while (1) {
while (amt_clicked < 15) {
if (button found) { // this is where I am lost
iimPlay("TAG POS={{amt_clicked}} TYPE=BUTTON ATTR=TXT:Get");
amt_clicked++;
}
}
iimPlay("WAIT SECONDS=60");
amt_clicked = 0;
}
This will run 20 times per second, using the window.setInterval() function:
var amt_clicked = 0;
var amt_cooldown = 1200;
setInterval(function(){
if (amt_cooldown === 0)
amt_cooldown = 1200;
else if (amt_cooldown < 1200)
amt_cooldown -= 1;
else if (amt_clicked > 15) {
amt_clicked = 1;
amt_cooldown -= 1;
} else {
amt_clicked -= 1;
//Click
}, 50);
You can use combination of setInterval and setTimeout.
I have added comments to code for you to understand.
var amt_clicked = 0;
var setTimeoutInProcess = false;
//processing the interval click function
setInterval(() => {
checkButtonAgain();
}, 200);
function checkButtonAgain() {
var element = document.getElementById('iNeedtoBeClicked');
//if clicked 15 times then need to wait for 60 seconds
if (amt_clicked === 15) {
if (!setTimeoutInProcess) {
setTimeoutInProcess = true;
setTimeout(function() {
//resetting the amt-clicked
amt_clicked = 0;
setTimeoutInProcess = false;
}, 60000);
} else {
console.log('waiting');
}
} else if (typeof(element) != 'undefined' && element != null) {
//triggering click and increasing the amt_clicked
element.click();
amt_clicked++;
}
console.log(amt_clicked);
}
<button id="iNeedtoBeClicked">Click ME Button</button>

Change this a function so I can pass a id into it- javascript

At the moment I am creating a Hangman Game and I have 26 different functions for each button on the web page. When a button is clicked its function works. What I want to do is change this so all I need is one function for all 26 buttons. Here is my HTML at the moment:
A
B
C
D
E
F
G
H
I
J
K
L
M
N
O
P
Q
R
S
T
U
V
W
X
Y
Z
Here is my Javascript:
function A(event) {
if (event.target.classList.contains("disabled")) {
event.preventDefault();
}
document.getElementById("A").style.opacity = "0.5";
event.target.classList.add("disabled");
for (var letter = 0; letter <= randomWord.length - 1; letter++) {
if (randomWord[letter] === "a") {
document.getElementById("letter_" + letter).innerHTML = "A";
if (oneClick === true) {
score = score + 1;
oneClick = false;
}
document.getElementById("Score").innerHTML = score;
} else if (randomWord.indexOf("a") == -1 && hasLooped === true) {
if (oneClick === true) {
score = score + 1;
oneClick = false;
}
document.getElementById("Score").innerHTML = score;
hasLooped = false;
mistakesLeft = mistakesLeft - 1;
document.getElementById("attempsLeft").innerHTML = mistakesLeft;
console.log(mistakesLeft);
if (mistakesLeft == 7) {
document.getElementById("part-1").style.display = "block";
}
else if (mistakesLeft == 6) {
document.getElementById("part-2").style.display = "block";
} else if (mistakesLeft == 5) {
document.getElementById("part-3").style.display = "block";
} else if (mistakesLeft == 4) {
document.getElementById("part-4").style.display = "block";
} else if (mistakesLeft == 3) {
document.getElementById("part-5").style.display = "block";
} else if (mistakesLeft == 2) {
document.getElementById("part-6").style.display = "block";
} else if (mistakesLeft == 1) {
document.getElementById("part-7").style.display = "block";
} else {
document.getElementById("part-8").style.display = "block";
}
}
}
}
What changes will I need to make to my HTML and Javascript so I no longer need to have 26 different functions? The stuff with in my javascript will also need to change.
Thanks
Change this a function so I can pass a id into it
Like you said, "pass an id into it"
onclick="oneFunction(event, this.id)"
function oneFunction(event, id){
// one code
}
You don't even need id. Just pass in this and you've got your element.
You can also attach the function by addEventListener something like
HTML
A
B
C
JS
var allButtons = document.getElementsByClassName('gamebutton');
//-------------as given in a tag as class----------^^^^
for(var i=0; i<allButtons.length; i++;){
allButtons[i].addEventListener('click', function (event){
//the single function by which your game would be executed
executeFunction(event, this.id);
//the id(eg:- A, B, C)----^^^-- depends
// on click is passing
})
}

How to create a pause in recursion function loop

I'm new here so sorry if dublicate.
I'm trying to write a sudoku solver using backtracking method to make it pass all data dynamically into the document with its each recursion. When I tried to use setInterval() or setTimeout() it doesn't work the way I want it to work. What I need should be similar to this
Here's the code:
function backtrack(position) {
if (position === 81) {
return true;
}
if (sudokuArray[position] > 0) {
backtrack(position + 1);
} else {
for (var x = 1; x <= 9; x++) {
if (isValid(x, parseInt(position / 9), position % 9) === true) {
sudokuArray[position] = x;
//some code that invokes putSudokuArrayBack function with a small delay
//everytime backtrack function is invoked
if (backtrack(position + 1) === true) {
return true;
}
}
}
sudokuArray[position] = 0;
return false;
}
}
function putSudokuArrayBack() {
for (var i = 0; i <= 81; i++) {
var indexString = '#val-' + parseInt(i / 9) + '-' + i % 9;
$(indexString).val(sudokuArray[i]);
}
}
Any ideas(if it's even possible)? Thanks in advance!

Categories

Resources