Is there a way to repeat a function in Javascript using the setTimeout function? For example, I need two functions to be called every five seconds. I have something like this:
$(document).ready(function(){
setTimeout('shiftLeft(); showProducts();', 5000);
});
but it only happens once, five seconds after page loads, and I need it to happen every five seconds.
Use setInterval() instead of setTimeout(), if you want your function to be executed repeatedly. setTimeout() delays the execution of your function for x seconds, while setInterval() executes your function every x seconds.
Both within the boundaries of the event queue of JavaScript, so don't be too confident, that you functions get executed at the exact time you specified
$(document).ready(function(){
setInterval( function(){ shiftLeft(); showProducts(); }, 5000);
});
Every x seconds can be done with setInterval:
$(document).ready(function(){
setInterval(function(){
shiftLeft(); showProducts();
}, 5000);
});
$(document).ready(function(){
setTimeout(function(){
shiftLeft(); showProducts();
}, 5000);
});
Related
This question already has answers here:
Why is the method executed immediately when I use setTimeout?
(8 answers)
Closed 6 years ago.
I'm having a javascript function which I have set an interval to execute every 30 seconds. This is my code:
function ping() {
// code ...
}
ping(); // call function when page loads for first time
// call function every 30 seconds
window.setInterval(function(){
ping();
}, 30000);
What I'd like to do is to delay the first call (right when the page loads for first time) for 5 seconds and then the function should execute again every 30 secs.
I have tried the setTimeout, but doesn't seem to work, it executes imidiatelly any ideas what I'm doing wrong ?
setTimeout(ping(), 5000); // delay first call for 5 secs
// call function every 30 seconds
window.setInterval(function(){
ping();
}, 30000);
I guess you are not waiting until timeout to declare the interval function.
There is a few different ways to do that, so let me suggest one:
function ping() {
// code ...
}
setTimeout(function () {
ping(); // call function when page loads for first time
// call function every 30 seconds
window.setInterval(function(){
ping();
}, 30000);
}, 5000);
You are calling it immediately on setTimeout(ping(), 5000);. You are setting the result of ping() as the timeout function. If you want ping to be called by the timeout, then either do setTimeout(ping, 5000); or wrap it in a closure, like you did the second time.
I have an ongoing while loop. In the while loop, there is a setTimeout(). I want to reset the timer AFTER the timer expires. In other words, when timer expires, it should do some specified actions, and then freshly start the timer again.
For example, in the following code, %%--Hi--%% should be printed only ONCE in 5 seconds. However, after 5 seconds, %%--Hi--%% is printed continuously. I tried clearTimeout but it looks like that clearTimeout can stop timer only before timer expires.
while(){
var timeoutHandle = setTimeout(function() {
console.log("%%--Hi--%%");
clearTimeout(timeoutHandle);
},
5000); //5 sec
}
Help please! Thanks!
It's not the timeout that's tripping you up, it's the infinite while loop. You're effectively creating thousands of timeouts every second. Moving the timeout outside of the infinite loop should solve your problem.
function timedAction() {
// your timed actions to be invoked every 5 seconds
setTimeout(timedAction, 5000); // start the next timeout
}
setTimeout(timedAction, 5000); // start the first timeout
while() {
// your continuously executing actions
}
There is no need to clear a timeout after it expires.
Alternatively you could also use setInterval, simplifying your code as follows:
function timedAction() {
// your timed actions to be invoked every 5 seconds
}
setInterval(timedAction, 5000); // start the interval
while() {
// your continuously executing actions
}
try this code:
logFun();
function logFun() {
console.log("%%--Hi--%%");
setTimeout(logFun, 5000);
}
or, you can try setInterval:
setInterval(function () {
console.log("%%--Hi--%%");
}, 5000);
The setTimeout method does not act like a sleep statement. Your while loop will continue to iterate continuously regardless of what time interval you set in the setTimeout method.
You should remove the while and simply use setInterval(). (Mentioned in yibuyisheng's answer. +1)
var myInterval = setInterval(function () {
console.log("%%--Hi--%%");
}, 5000);
If you want to stop the interval, run the following:
clearInterval(myInterval);
Your problem is that setTimeout is an asynchronous function, so your code doesn't wait for it to finish before looping again. To get around this you have to create your new timer inside the previous timer.
Likewise you have to call any actions you want to execute from inside the timer and can't just call them from in the while loop, because they won't wait for the timer to finish.
function logFun() {
console.log("%%--Hi--%%");
// execute actions
setTimeout(logFun, 5000);
}
This is what yibuyisheng has done with his answer that just showed up. (Still posting because the answer was not explained.)
Alternatively, if you must create the setTimeout() from the while loop, you could have a boolean (true/false) lock it. This is not as clean as yibuyisheng's answer, but it also allows you to add as much logic as you'd like to control enabling and disabling the timeout.
Example:
window.isTimeoutLocked = false;
while(true) {
if (!window.isTimeoutLocked) {
var myFunction = function () {
console.log("%%--Hi--%%");
//The timeout has fired. Unlock it for the next one.
window.isTimeoutLocked = false;
}
window.setTimeout(myFunction, 5000);
//Timeout is queued. Lock this code until the timeout fires.
window.isTimeoutLocked = true;
}
}
Also, I doubt that an infinite while loop is best for your upstream code. There is probably a callback that you can hook into, like requestAnimationFrame or some relevant event.
I have the following code:
// After 8 seconds change the slide...
var timeout = setTimeout("changeSlide()", 8000);
$('div.slideshow').mouseover(function() {
// If the user hovers the slideshow then reset the setTimeout
clearTimeout(timeout);
});
$('div.slideshow').mouseleave(function() {
clearTimeout(timeout);
var timeout = setTimeout("changeSlide()", 8000);
});
What I want to happen is make the function changeSlide run EVERY 8 seconds in a loop unless someone hovers the slideshow div. When they remove the cursor then do the timeout again!
However the loop only happens once and the hover doesn't stop the timeout or start it again :/
EDIT:
This loops great but the hover on and off causes the function to run multiple times:
// After 8 seconds change the slide...
var timeout = setInterval(changeSlide, 2000);
$('div.slide').mouseover(function() {
// If the user hovers the slideshow then reset the setTimeout
clearInterval(timeout);
});
$('div.slide').mouseleave(function() {
clearInterval(timeout);
var timeout = setInterval(changeSlide, 2000);
});
You have a couple issues here. First off, when you set a timeout, you need to store the return of that function call into a variable if you potentially want to stop it.
var slide_timer = setTimeout(changeSlide, 8000);
Second, when you call clearTimeout (rather than clearInterval), you need to pass it an argument. What argument? That variable you stored when you called setTimeout
clearTimeout(slide_timer);
Third, when you use setTimeout, it only fires once. setInterval will continue to fire, then you'd use clearInterval to stop it.
There is an issue in timing with using intervals rather than timeouts. The browser treats them subtly differently, and it may be important to your code to know the difference and use the proper method. If you use intervals, since they only fire once, you'll have to re-establish the timeout every time it fires.
var slide_timer = setTimeout(function () {
changeSlide();
var slide_timer = setTimeout(changeSlide, 8000);
}, 8000);
OR
var slide_timer = setTimeout(changeSlide, 8000);
...
function changeSlide() {
... your code ...
var slide_timer = setTimeout(changeSlide, 8000);
}
(I prefer the former method)
And lastly, whether you use timeouts or intervals, don't pass a string to setTimeout, pass a function reference. See the sample code above, or like this:
var slide_timer = setTimeout("changeSlide()", 8000); // <--- DON'T
var slide_timer = setTimeout(changeSlide, 8000); // <--- DO
var slide_timer = setTimeout(function () { // <--- DO
changeSlide() ;
// other script
}, 8000);
Putting it all together:
// After 8 seconds change the slide...
var slide_timer = setTimeout(changeSlide, 8000);
$('div.slideshow').hover(function() {
// If the user hovers the slideshow then reset the setTimeout
clearTimeout(slide_timer);
}, function() {
slide_timer = setInterval(changeSlide, 8000);
});
Documentation
clearTimeout - https://developer.mozilla.org/en/DOM/window.clearTimeout
setTimeout - https://developer.mozilla.org/en/DOM/window.setTimeout
clearInterval - https://developer.mozilla.org/en/DOM/window.clearInterval
setInterval - https://developer.mozilla.org/en/DOM/window.setInterval
SO answer discussing the subtle difference between intervals and timeouts - https://stackoverflow.com/a/7900293/610573
When you specify setTimeout (or setInterval), it returns a value that is then used for clearTimeout and clearInterval. Correct usage is as follows:
var timeout = setTimeout(changeSlide, 8000);
clearTimeout(timeout);
Also note I am using clearTimeout, not clearInterval.
You'll also notice that I did not put quotes around 'changeSlide', and that I dropped the parens. When passing a string to setTimeout, eval() is used. eval() is, in general, recommended to be avoided. So, instead, we pass it the direct reference to the function (without quotes). We do not use parens, because that would actually call changeSlide() right away, instead of deferring execution to setTimeout (and would pass, as an argument to setTimeout, the result of changeSlide())
EDIT: To get it to run continously, you have to call setTimeout again after each changeSlide call. setTimeout runs once. As an alternative, you can use setInterval, which automatically repeats. The one caveat to setInterval is that if the interval is too short and the callback it calls takes a long time to run, you can end up with a bunch of intervals queued up to execute one after another, without delay. An 8 second interval would likely not face this problem.
EDIT 2:
var timeout;
var changeSlide = function(){
// do something to change slides
clearTimeout(timeout);
timeout = setTimeout(changeSlide, 8000);
}
// queue up the first changeSlide, all others happen inside changeSlide
timeout = setTimeout(changeSlide, 8000);
$('div.slideshow').mouseleave(function() {
clearTimeout(timeout);
var timeout = setTimeout(changeSlide, 8000);
});
I think you need setInterval and not setTimeout, since:
setTimeout(expression, timeout); runs the code/function once after the timeout
setInterval(expression, timeout); runs the code/function in intervals, with the length of the timeout between them
In the end this worked the best (but I won't accept this as my answer as it was others who helped me get to this point)
// After 8 seconds change the slide...
var slide_timer = setInterval(changeSlide, 2000);
$('div.slideshow').hover(function() {
// If the user hovers the slideshow then reset the setTimeout
clearInterval(slide_timer);
}, function() {
slide_timer = setInterval(changeSlide, 2000);
});
Your issue may be the mouseover event. The mouseover event bubbles, so if you have a nested HTML structure, then the event may be called more than once. If you are using jQuery, you should use the mousenter event, which will only get called once for the element.
On a different note, instead of using setInterval use a setTimeout pattern. Something like this:
//Immediately Invoked Function Expression that gets called immediately
(function() {
//Make the initial call to your setTimeout function
repeat();
//Function will constantly be called
function repeat() {
setTimeout(function() {
//(Put your conditional logic here)
console.log('test');
repeat();
}, 2000);
}
})();
I've done this a month before...
But now its not working...
The code is
window.onload = function(){
setTimeout(function(){
alert("Hello");
}, 10000);
};
This is written in script in head of the test.php page.
The script and other tags are correct.
I would like to call a specific function every 10 seconds. The alert just shows once only. This is problem in every browser....
After this testing i would like to check the url every 2 seconds and call an AJAX function.
Any Help??
That's what setTimeout does (executes once after a specified interval). You're looking for setInterval (calls a function repeatedly, with a fixed time delay between each call to that function):
window.onload = function(){
setInterval(function(){
alert("Hello");
}, 10000);
};
Use setInterval instead.
var fn = function(){alert("Hello")};
It is possible using setTimeout:
window.onload = function(){ setTimeout( function(){ fn();window.onload() },10000) };
but the best solution is setInterval:
window.onload = function() { setInterval(fn,10000)};
setTimeout is intended for one-time run. Look at setInterval function.
how can I execute a javascript program 30 after page loads, and I have to execute it repeatedly in 30 seconds. I would like to use jquery since I already included in my document
Thank you guys
You could use the window.setTimeout method:
window.setTimeout(function() {
// This will execute 30s after the page loads
// and it will execute only once
}, 30000);
If you want to repeat the execution of the function on every 30 seconds you could use the setInterval method.
As far as jquery is concerned you don't need to to use it for such a simple task as it is already built into javascript.
You want setInterval() here, like this:
setInterval(function() {
alert("It's been 30 seconds");
}, 30000);
setInterval() will fire after the delay (so 30 seconds in) then again every time the delay is up (every 30 seconds as desired).
If you want to execute it 30 times, once a second, you'd use setInterval.
var interval = window.setInterval(function() {
// do stuff
}, 1000);
window.setTimeout(function() {
window.clearInterval(interval);
}, 30 * 1000);
$.ajaxSetup({
cache: false
});
setInterval(function() {
$("#data1").load('1.php');
}, 30000);
});
Just substitute your jQuery function in :)