Javascript ClearTimeout doesnt work - javascript

I'm looking for a solution for my code. My clearTimeout function doesn't work in the stop(); and start(); functions, does anybody know how to fix this?
The stop, start and reset button have all a setTimeout function. What I would like to do is that if is clicked at one of the buttons, the other two buttons have cleartimeout. But for somehow it doesn't working right now.
var isTimerStarted;
var timeOutElse;
var timeOut;
var opnieuw;
function start() {
clocktimer = setInterval("update()", 1);
x.start();
isTimerStarted = true;
timeOutElse = setTimeout(function(){
document.getElementById("scherm3").style.display = "block";
document.getElementById("scherm2.2").style.visibility = "hidden";
}, 8000)
}
function stop() {
x.stop();
clearInterval(clocktimer);
isTimerStarted = false;
timeOut = setTimeout(function(){
document.getElementById("scherm4").style.visibility = "visible";
document.getElementById("scherm2.2").style.visibility = "hidden";
}, 4000)
}
function reset() {
stop();
x.reset();
update();
opnieuw = setTimeout(function(){
document.getElementById("scherm3").style.display = "block";
document.getElementById("scherm2.2").style.visibility = "hidden";
}, 10000);
clearTimeout(timeOut);
clearTimeout(timeOutElse);
document.getElementById("buttontimer").value = "Start";
}
setTimeout(start, 5000);
function toggleTimer(event) {
if (isTimerStarted) {
stop();
event.target.value = 'Start';
clearTimeout(opnieuw);
clearTimeout(timeOutElse);
} else {
start();
event.target.value = 'Stop';
clearTimeout(opnieuw);
clearTimeout(timeOut);
}
}

There's nothing wrong with your code, from what I can tell.
But I think you might have forgot to remove a line from it.
setTimeout(start, 5000); is creating timeouts after 5 seconds whatever/whenever you click a thing.
It is what could create timing issues.
Here's a scenario that could happen:
you click
toggleTimer() -> start() -> create timeout and interval
5s later your setTimeout(start, 5000) executes and reassign your timeout and interval variables
you re-click
latest timeout and interval gets cleared, but not the first ones
Just to be safe, you could clear, at the beginning of each of your functions, the timeouts and intervals you're creating in the said function.
This way, you will always clear timeouts and intervals that gets created.

Related

clearTimeout not working on mouseup event

Why is timeout not being cleared in this setup? How can I make up() stop the delayed actions from running?
var active = false;
var delay;
window.addEventListener("mousedown", down, false);
window.addEventListener("mouseup", up, false);
window.addEventListener("mousemove", move, false);
function down(e) {
active = true;
console.log("down")
window.scrollTo(0,document.body.scrollHeight);
}
function up(e) {
active = false;
clearTimeout(delay); //expecting this to clear delay
console.log("up")
window.scrollTo(0,document.body.scrollHeight);
}
function move(e) {
if (active) {
delay = setTimeout(function() {
console.log("move")
window.scrollTo(0,document.body.scrollHeight);
}, 50);
}
}
Expecting delay to be cleared on mouseup but it still executes.
You keep making timeouts on every movement. It does not replace the last one...
Your code is basically this
delay = setTimeout(function() { } <-- will run
delay = setTimeout(function() { } <-- will run
delay = setTimeout(function() { } <-- will run
delay = setTimeout(function() { } <-- will run
delay = setTimeout(function() { } <-- will run
delay = setTimeout(function() { } <-- will run
delay = setTimeout(function() { } <-- cancels this one
window.clearTimeout(delay)
So you need to remove it before you create a new one
if (active) {
if (delay) window.clearTimeout(delay)
delay = setTimeout(function() {
console.log("move")
window.scrollTo(0,document.body.scrollHeight);
}, 50);
}
If you need to move to fire more than once, that you want to look into throttling scripts.
So, I've learned from the replies that setTimeout produces a new independent timer every time move() is executed. My understanding was that each new timer overwrites the previous one but as this is not the case I had to think of something else.
I did't really explain what I actually needed to achieve with the delay so let me clarify. I want to create a timeout for an action if that action has not been executed for x amount of time. Using setTimeout on the action it self created the problem that the action would still potentially have multiple queued executions waiting to happen even after mouseup events.
So instead I used setTimeout on a new variable that acts as a lock to the action. The result is the following code:
var active = false;
var actionTimeout = false;
var actionTimeStamp;
var actionLock = false;
window.addEventListener("mousedown", down, false);
window.addEventListener("mouseup", up, false);
window.addEventListener("mousemove", move, false);
function down(e) {
active = true;
console.log("down")
window.scrollTo(0,document.body.scrollHeight);
}
function up(e) {
active = false;
console.log("up")
window.scrollTo(0,document.body.scrollHeight);
}
function move(e) {
if (active) {
if ((Date.now() - actionTimeStamp > 500) && (!actionTimeout)) { // get time elapsed and compare to threshold (500ms)
actionTimeout = true; //this is for the if statement above to prevent multiple timeouts
actionLock = false; // set the lock
setTimeout(function() { // remove lock after 50ms
actionTimeout = false;
actionLock = true;
actionTimeStamp = Date.now(); // timestamp here to make sure we don't lock again to soon. (helps if setTimeout is => than threshold.
}, 50);
}
if (actionLock) { //do our action
console.log("move")
window.scrollTo(0,document.body.scrollHeight);
actionTimeStamp = Date.now(); // timestamp last execution
}
}
}
Thanks to everyone for chipping in with comments and answers. Really appreciated.
Answer:
There are a few things to adjust in your code:
Instead of continuously reassigning delay with a new Timeout Timer, simply use an Interval.
You should only set the Timer if the state is active AND delay does not exist already. this stops multiple Timers from existing
There are a few things to adjust and understand about Timers in JavaScript:
When you set a Timer, the variable that houses the Timer is set to return an Integer. This is the ID of the Timer in the current scope.
When you clear a Timer, the variable isn't reset to undefined - it stays the same Integer/ID. This is because you're not clearing the variable, the scope is stopping the Timer that matches the ID the variable houses.
Because of the above you have to explicitly set the variable housing the Timer to undefined (or some other falsy value) after clearing it for an existence check to work.
var active = false;
var delay;
window.addEventListener("mousedown", down, false);
window.addEventListener("mouseup", up, false);
window.addEventListener("mousemove", move, false);
function down(e) {
active = true;
console.log("down")
window.scrollTo(0,document.body.scrollHeight);
}
function up(e) {
active = false;
clearTimeout(delay); //expecting this to clear delay
delay = undefined;
console.log("up")
window.scrollTo(0,document.body.scrollHeight);
}
function move(e) {
if (active) {
if(!delay) {
delay = setInterval(function() {
console.log("move")
window.scrollTo(0,document.body.scrollHeight);
}, 50);
}
}
else { //fallback in case of Browser Queuing issues
if(delay) {
clearTimeout(delay);
delay = undefined;
}
}
}
Edited
Due to comments with issues I added a fallback in mousemove that will remove the timer if the state is inactive, but delay is still defined. I don't believe that you technically should need this, but in practice Browser Event Queuing and Timers occasionally don't get along as expected.

Button to start/stop an infinite loop through functions with delay between each

I'm trying to create a function that on the click of a button will start a loop through each function with a 5 second delay between each and loop infinitely until the button is clicked again. I'm close with this, but after 5 seconds, it only just executes the last function in the set (tuesday) and does not iterate through them with a delay between each.
function links() {
safety
daily
monday
tuesday
}
var intervalId;
function toggleIntervalb() {
if (!intervalId) {
intervalId = setTimeout(links, 5000);
} else {
clearInterval(intervalId);
intervalId = null;
}
}
function safety(){
document.getElementById("fires").style.display = 'none';
document.getElementById("safety").style.display = 'block';
document.getElementById("daily").style.display = 'none';
document.getElementById("monday").style.display = 'none';
document.getElementById("tuesday").style.display = 'none';
}
function daily(){
document.getElementById("fires").style.display = 'none';
document.getElementById("safety").style.display = 'none';
document.getElementById("daily").style.display = 'block';
document.getElementById("monday").style.display = 'none';
document.getElementById("tuesday").style.display = 'none';
}
function monday(){
document.getElementById("fires").style.display = 'none';
document.getElementById("safety").style.display = 'none';
document.getElementById("daily").style.display = 'none';
document.getElementById("monday").style.display = 'block';
document.getElementById("tuesday").style.display = 'none';
function tuesday(){
document.getElementById("fires").style.display = 'none';
document.getElementById("safety").style.display = 'none';
document.getElementById("daily").style.display = 'none';
document.getElementById("monday").style.display = 'none';
document.getElementById("tuesday").style.display = 'block';
**2nd Attempt:
Closer with this (includes button)
New to jsfiddle - can't make my code work here: https://jsfiddle.net/unqrhxtp/16
So, I am also including the pastebin (save as .html and open): https://pastebin.com/EwHVqmHJ
Currently, the code stops after executing the first function. It appears to loop on the first element only (if you click another link manually, it forces back to the first function in the set).
Thanks in advance.
Changing this line:
intervalId = setTimeout(links, 5000);
from a setTimeout to a setInterval will probably fix that
intervalId = setInterval(links, 5000);
Update
After reading your updated question I think something like this will solve your problem:
// Gather functions in an array, easier to loop trough
var links = [
safety,
daily,
monday,
tuesday,
wednesday,
thursday
]
function cyclelinks() {
links.forEach(function(link, index) {
var delay = index * 5000;
var fn = links[index];
setTimeout(fn, delay)
});
}
var intervalId;
function toggleInterval() {
var btn = document.getElementById("logo");
if (!intervalId) {
var delay = links.length * 5000; // repeat after all functions are called with 5 sec delay
cyclelinks()
intervalId = setInterval(cyclelinks, delay);
} else {
clearInterval(intervalId);
intervalId = null;
location.reload();
}
}
You should use setInterval because setTimeout runs after gived time means it works correctly because. If you run this code step by step then you can see what i am saying. When cursor on the settimeout your functions doesnt work immediately it will wait 5 secs.
I hope i could help
I managed to come up with a solution, although I'm not totally happy with it. Mostly because it forces me to wait a full 90 seconds before the looping starts. For now, this will do, but I'll leave this open in hopes someone will post a better solution.
//Loop through links upon click
function cyclelinks() {
setTimeout(safety, 10000);
setTimeout(daily, 20000);
setTimeout(monday, 30000);
setTimeout(tuesday, 40000);
setTimeout(wednesday, 50000);
setTimeout(thursday, 60000);
}
var intervalId;
function toggleInterval() {
var btn = document.getElementById("logo");
if (!intervalId) {
intervalId = setInterval(cyclelinks, 90000);
} else {
clearInterval(intervalId);
intervalId = null;
location.reload();
}
}

use onmousemove to reset setTimeout() to start over again(・・?

when mouse moves, the timer function cancelled =="
but i actually want it to count from the beginning instead.
function w()
{
if (parent.C.location == "http://119.247.250.128/wasyoku/home/prime.html")
{ parent.C.location = "weather.html";
wTout = setTimeout(function(){ parent.C.location = "prime.html"; }, wT);
}
else { parent.C.location = "prime.html"; clearTimeout(wTout); }
}
document.onmousemove.clearTimeout(wTout);
do i really need to setTimeout again(・・?
wTout = setTimeout(function(){ parent.C.location = "prime.html"; }, wT);
Yes, if you clear the timeout you have to set it again.
Another thing you can do is set a variable as the last time you moved the mouse and on the ontimeout you can set another settimeout if you moved the mouse in XX seconds
var sto = null;
function myTimeout() {
window.clearTimeout(sto);
sto = setTimeout(function() {
console.log("setTimeout's working");
}, 2000);
}
someElement.addEventListener('mousemove', function() {
myTimeout();
});
jsfiddle DEMO

How to pause and resume jquery interval

I have made a custom slider with jQuery. For this I have used setInterval function:
timer = setInterval(function() {}, 8000);
But I cannot pause and resume the interval. I have 2 buttons (play, pause) which I want to use for. Lets say I click pause after 3 sec, and then resume it. So it should stay in that slider for 5 more seconds and then go to the next one and continue 8 seconds each. I have seen this kinda slider with mouseover pause, but can't do it by myself. I have tried this:
clearInterval(timer);
But this seems reset the interval, don't pause. Can anyone help :)
I'm not entirely sure that's something native to jQuery, however, you could use a flag to pause it, and check in your setInterval whether to execute.
Edit:
Found something that might be useful to you, the jquery-timer
Alternitively, you can keep track of the id set by setInterval, and clear out out when you'd like to pause. Then you can set it again when you wish to resume:
var id = window.setInterval(<code>); //create
window.clearInterval(id); //pause
id = window.setInterval(<code>); //resume
there are two ways of accomplish this:
Clearing the interval everytime you pause and starting a new interval when you resume it.
Having a flag to tell the function in the interval when it is paused and it should not do anything.
The first solution would work like this:
let intervalId = false;
const intervalLength = 8000; // 8 seconds
function intervalFunction () {
// do stuff.
}
startButton.onclick = function () {
if (intervalId === false) {
intervalId = setInterval(intervalFunction, intervalLength);
}
}
pauseButton.onclick = function () {
if (intervalId !== false) {
clearInterval(intervalId);
intervalId = false;
}
}
// auto start it:
intervalId = setInterval(intervalFunction, intervalLength);
The second solution would work like this:
var isRunning = true;
var interval = setInterval(function() {
if (!isRunning) {
// not running, do nothing
} else {
// it is running, do stuff.
}
}, 8000);
pauseButton.onclick = function () {
isRunning = false;
};
startButton.onclick = function () {
isRunning = true;
};
I am not complete sure, that what you are asking for, is the right thing you are showing us... setInterval basically is pure native javascript and in my opinion not worth using! If you wan't to set your timeouts via jquery try this link: http://jchavannes.com/jquery-timer. You can find usages there...
Now on to your problem... you need a state to check wether the slider has to slide or not... simply set a bool like this...
var timer;
var doSlide = false;
var i = 0;
function Slide(){
timer = setTimeout(function(){
if(doSlide == true){
Slide();
i++; // Same as i = i + 1
console.log('Sliding');
if(i == 3) AbortSlide(); /* Abort on third slide! Dont use this in your logic!*/
} else if(doSlide == false){
console.log('Sliding aborted untill next RunSlide() call!')
clearTimeout(timer);
}
},1000);
}
function AbortSlide(){
doSlide = false;
i = 0; // Resetting the count! Dont use this in your logic!
}
function RunSlide(){
doSlide = true;
Slide();
}
RunSlide();
You could also empty the interval in the abort method:
function AbortSlide(){
doSlide = false;
clearTimeout(timer);
i = 0; // Resetting the count! Dont use this in your logic!
}
Here is a working fiddle i made for you to understand what timers and intervals are for: https://jsfiddle.net/q5qzmv68/7/
Hope this helps! Cheers!

Resetting a setTimeout

I have the following:
window.setTimeout(function() {
window.location.href = 'file.php';
}, 115000);
How can I, via a .click function, reset the counter midway through the countdown?
You can store a reference to that timeout, and then call clearTimeout on that reference.
// in the example above, assign the result
var timeoutHandle = window.setTimeout(...);
// in your click function, call clearTimeout
window.clearTimeout(timeoutHandle);
// then call setTimeout again to reset the timer
timeoutHandle = window.setTimeout(...);
clearTimeout() and feed the reference of the setTimeout, which will be a number. Then re-invoke it:
var initial;
function invocation() {
alert('invoked')
initial = window.setTimeout(
function() {
document.body.style.backgroundColor = 'black'
}, 5000);
}
invocation();
document.body.onclick = function() {
alert('stopped')
clearTimeout( initial )
// re-invoke invocation()
}
In this example, if you don't click on the body element in 5 seconds the background color will be black.
Reference:
https://developer.mozilla.org/en/DOM/window.clearTimeout
https://developer.mozilla.org/En/Window.setTimeout
Note: setTimeout and clearTimeout are not ECMAScript native methods, but Javascript methods of the global window namespace.
You will have to remember the timeout "Timer", cancel it, then restart it:
g_timer = null;
$(document).ready(function() {
startTimer();
});
function startTimer() {
g_timer = window.setTimeout(function() {
window.location.href = 'file.php';
}, 115000);
}
function onClick() {
clearTimeout(g_timer);
startTimer();
}
var myTimer = setTimeout(..., 115000);
something.click(function () {
clearTimeout(myTimer);
myTimer = setTimeout(..., 115000);
});
Something along those lines!
For NodeJS it's super simple:
const timeout = setTimeout(...);
timeout.refresh();
From the docs:
timeout.refresh()
Sets the timer's start time to the current time, and reschedules the timer to call its callback at the previously specified duration adjusted to the current time. This is useful for refreshing a timer without allocating a new JavaScript object.
But it won't work in JavaScript because in browser setTimeout() returns a number, not an object.
This timer will fire a "Hello" alertbox after 30 seconds. However, everytime you click the reset timer button it clears the timerHandle then re-sets it again. Once it's fired, the game ends.
<script type="text/javascript">
var timerHandle = setTimeout("alert('Hello')",3000);
function resetTimer() {
window.clearTimeout(timerHandle);
timerHandle = setTimeout("alert('Hello')",3000);
}
</script>
<body>
<button onclick="resetTimer()">Reset Timer</button>
</body>
var redirectionDelay;
function startRedirectionDelay(){
redirectionDelay = setTimeout(redirect, 115000);
}
function resetRedirectionDelay(){
clearTimeout(redirectionDelay);
}
function redirect(){
location.href = 'file.php';
}
// in your click >> fire those
resetRedirectionDelay();
startRedirectionDelay();
here is an elaborated example for what's really going on http://jsfiddle.net/ppjrnd2L/
i know this is an old thread but i came up with this today
var timer = []; //creates a empty array called timer to store timer instances
var afterTimer = function(timerName, interval, callback){
window.clearTimeout(timer[timerName]); //clear the named timer if exists
timer[timerName] = window.setTimeout(function(){ //creates a new named timer
callback(); //executes your callback code after timer finished
},interval); //sets the timer timer
}
and you invoke using
afterTimer('<timername>string', <interval in milliseconds>int, function(){
your code here
});
$(function() {
(function(){
var pthis = this;
this.mseg = 115000;
this.href = 'file.php'
this.setTimer = function() {
return (window.setTimeout( function() {window.location.href = this.href;}, this.mseg));
};
this.timer = pthis.setTimer();
this.clear = function(ref) { clearTimeout(ref.timer); ref.setTimer(); };
$(window.document).click( function(){pthis.clear.apply(pthis, [pthis])} );
})();
});
To reset the timer, you would need to set and clear out the timer variable
$time_out_handle = 0;
window.clearTimeout($time_out_handle);
$time_out_handle = window.setTimeout( function(){---}, 60000 );

Categories

Resources