'Looping' JavaScript functions - javascript

I have the below script.
function slideShow1(){
document.getElementById('dynimg').src="Other/noctis.jpg";
var timer1 = setTimeout(slideShow2(),5000);
}
function slideShow2(){
document.getElementById('dynimg').src="Other/retriever.jpg";
var timer2 = setTimeout(slideShow3(),5000);
}
function slideShow3(){
document.getElementById('dynimg').src="Other/miningop2.jpg";
var timer3 = setTimeout(slideShow1(),5000);
}
It's crude, I know... And it's also not working. The idea is for each function to trigger the next after a given period and therefore creating a slideshow where and img is changed repeatedly. I am trying to use body onload="slideShow1()"

Those parentheses are causing your function to be executed immediately.
setTimeout(slideShow2(), 5000);
As such, you think you're passing your function to setTimeout but you're actually executing your function and passing its return value (undefined in this case).
So, your function gets called immediately and setTimout has nothing to execute five seconds later.
Just remove the parentheses:
function slideShow1(){
document.getElementById('dynimg').src = "Other/noctis.jpg";
setTimeout(slideShow2, 5000);
}
function slideShow2(){
document.getElementById('dynimg').src = "Other/retriever.jpg";
setTimeout(slideShow3, 5000);
}
function slideShow3(){
document.getElementById('dynimg').src = "Other/miningop2.jpg";
setTimeout(slideShow1, 5000);
}

Related

Why I can not clearInterval in the following example?

I have the following issue. While the timer_mou starts counting, when the pause equals closeit it does not clear the interval.
What am I missing here?
function my_timer(pause){
console.log('function: '+pause);
var timer_mou = setInterval(function() {
console.log('counting');
}, 5000);
if (pause == 'closeit') {
clearInterval(timer_mou);
}
}
Just put the setInterval out of the pause function to define the variable timer_mou in the global scope, then when you call your function it will clear it correctly, instead of defining it on every call of the function, check the working example below.
Hope this helps.
var i = 0;
var timer;
start();
$('#pause').on('click',function(){
pause()
})
$('#restart').on('click',function(){
restart()
})
function pause(){
clearInterval(timer);
}
function restart(){
i=0;
pause()
start();
}
function start(){
timer = setInterval(function() {
i++;
console.log('Counting '+i);
},1000);
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<button id='pause'>Pause</button>
<button id='restart'>Restart</button>
You need to define timer_mou outside of the function. In your case you won't be able to clear the timer as you have lost reference to the timer and you create a new timer instance with every function call.
Try something like:
var timer_mou;
function start_timer() {
timer_mou = setInterval(function() {
console.log('counting');
}, 5000);
}
function stop_timer() {
clearInterval(timer_mou);
}
This is a very annoying problem that has to do with scope. When you declare the setInterval inside of your function, the only place you can clear it is inside of that iteration of the function. So,
my_timer("") //Starts a timer in the function
my_timer("closeit") //Starts a timer in the function, then stops it
//with the other timer running in the background
You can reduce the problem to the fact that your interval gets declared multiple times, and you can only stop it inside of the function. So, if you want the my_timer function to start the timer, but stop if you give it the parameter of "pauseit", you could implement something like this:
function my_timer(pause){
console.log('function: '+pause);
if(typeof timer_mou === "undefined"){ //If the interval already exists, don't start a new one
timer_mou = //Defines in global scope
setInterval(function() {
console.log('counting');
}, 5000);
}
if (pause == 'closeit') {
clearInterval(timer_mou);
}
}
So, in the new version of your function, it checks if the interval is defined, and if not, defines it in the global scope so you can remove it later.
Done on mobile, so that's my excuse for bad formatting and spelling errors.

Why does setInterval initiate when I'm only assigning it?

I'm assigning to a variable, a function that uses setInterval, but I don't want the function to run until I call it. However, the function is running from just the assignment statement.
sessionClock = setInterval(function() {
console.log("Hi")
}, 1000)
I have also tried like this:
sayHi = function() {
console.log("Hi");
}
var sayHiStarter = setInterval(sayHi, 1000);
Both of these initiate the function and will log "Hi" to the console.
Why is it running on assignment? And what can do I do fix this?
If you only want to bind a function to setInterval, but call it later, you can use bind:
var sessionClock = setInterval.bind(null, function() {
console.log("Hi")
}, 1000);
//... later
var myInterval = sessionClock(); // start the timer
// ... later if you need to clear it
clearInterval(myInterval);
In principle, bind returns a new function that calls your original function (in this case, setInterval) with predefined arguments. So when you call sessionClock, that returned function is called. There a other aspects to bind, but they don't seem to apply in this context.
The call to setInterval does not return a function, but an identification for the created interval. This id is used to remove the interval when you don't want it to execute anymore:
sessionClock = setInterval(function() {
console.log("Hi")
}, 1000)
...
clearInterval(sessionclock);
What you want is something like this:
sessionClock = function () {
return setInterval(function() {
console.log("Hi")
},
1000);
}
//When needed
var intervalId=sessionClock();

the counter is doubling

While working on my personal project, I've encountered a problem. The problem is every time my function loops the counter counts twice.
JavaScript Code:
function punch(){
var hit;
var h1=100;
h1-=1;
counter++;
hit=setInterval('punch()',2000);
}
What I wanted it to do is that every 2000 milliseconds the counter goes up 1.
In your original code every time the function punch is called is called again internally.
var counter = 0;
function punch(){
var h1=100;
h1-=1;
counter++;
}
var hit = setInterval(punch,2000);
window.setInterval(function(){
/// call your function here
}, 2000);
Call your function where commented and inside the function increment your counter.
var counter = 0;
var h1=100;
setInterval(punch,2000);
function punch(){
h1-=1;
counter++;
}
Here you go: http://jsfiddle.net/9JLdU/3/
<div id="counter"></div>
<script>
var hit;
var counter = 0;
window.punch = function()
{
var h1=100;
h1-=1;
counter++;
document.getElementById('counter').innerHTML=counter;
}
hit = setInterval('punch()',2000);
</script>
setInterval will cause the function to be called about every 2 seconds until cancelled. By including another call to setInterval within the function, another sequence of calls is established each time it is called, so eventually you'll have thousands of instances running, each incrementing the counter.
So either use one call to setInterval, or have the function call itself using setTimeout, which only runs once. Also, it's preferred to pass a function reference to setInterval and setTimeout as passing a string calls the Function constructor and is effectively a call to eval, which is needlessly expensive in terms of system resources.
var counter = 0;
function punch() {
// ...
counter++;
hit = setTimeout(punch, 2000);
}
punch();
or
var counter = 0;
function punch() {
// ...
counter++;
}
setInterval(punch, 2000);
The advantage of setTimeout is that you can easily vary the delay based on some other logic, or stop the sequence without cancelling the timeout.
Note that when doing:
hit = setInterval(...);
the value of hit is an index that can be used to cancel the interval, it is not the value returned by punch (which is undefined since there is no return statement).
The setInterval() method calls a function or evaluates an expression at specified intervals (in milliseconds).
The setInterval() method will continue calling the function until clearInterval() is called, or the window is closed.
Read about setInerval() Here
Syntax
setInterval(function,milliseconds)
Working Example here
<script>
var hit = 100;
counter = 0;
var myVar = setInterval(function() {punch()}, 1000);
function punch() {
hit--;
counter++;
}
</script>

Output of one sample program of javascript is giving wrong answer

I was reading one book named 'Hands on node.js' by 'Pedro Teixiera'.
I was trying to execute one same program giving in that book that will call a function and that function is calling the same function recursively within some interval again and again.
But when I executed, it gives only one time '1' and stops
Please help me to figure it out why it is not able to call the same function again.
Sample program is as follows:
var schedule = function(timeout, callbackfunction) {
return {
start: function() {
setTimeout(callbackfunction, timeout)
}
};
};
(function()
{
var timeout = 10000; // 1 second
var count = 0;
schedule(timeout, function doStuff() {
console.log(++ count);
schedule(timeout, doStuff);
}).start(timeout);
})();
You aren't actually calling the function again. start() is the part that starts the timer.
schedule( timeout, function doStuff() {
console.log( ++count );
schedule( timeout, doStuff ).start(); // <--- added .start() here
}).start();
(Also note that the start() function doesn't take parameters.)
with some interval again and again
No, for that you would have used setInterval instead of setTimeout.
it gives only one time '1' and stops
Yes, your doStuff function doesn't put a new timeout. Your odd schedule function needs to be .start()ed!

setInterval exits after first iteration. Please help me rectify this snippet?

Can someone help me rectify the issue related to the setInterval? I'm fairly new to JavaScript, I'm not sure what's wrong here. I have this block in my page:
GlobalTicker.prototype.TickElements = function () {
this.timer = setInterval(this.initializeElement.apply(this) , 1000);
};
GlobalTicker.prototype.initializeElement = function () {
for (var i = 0; i < this.tickerElements.length; i++) {
var existingRun = this.tickerElements[i].secs;
var elementId = $('#' + this.tickerElements[i].id + ' .comment-editor').find('.ticker');
existingRun -= 1;
$(elementId).text(existingRun);
if (existingRun === 0) {
$(elementId).remove();
this.tickerElements.splice(i, 1);
if (this.tickerElements.length == 0) clearInterval(this.tickerElements.timer);
}
}
};
Then somewhere in the code, I have this call in a function
var objTicker = new GlobalTicker();
CommentManagement.prototype.createComment = function (domObject) {
objTicker.TickElements();
};
This function call actually invokes the setInterval function and runs the first iteration and jumps to the initialiseComment(); but once this block is executed, on the next interval, instead of executing the initialiseComment(); again, it jumps back to my function call CreateComment();. What am I doing wrong here?
setInterval() requires a function reference. You were calling the function itself and passing the return result from executing the function (which was undefined) to setInterval(). Since that return value is not a function, there was no callback function for setInterval() to call. Thus, your method was executed once when you first called it, but couldn't be called by the interval.
To fix it, you should change from this:
this.timer = setInterval(this.initializeElement.apply(this) , 1000);
to this:
var self = this;
this.timer = setInterval(function() {self.initializeElement()}, 1000);
Note, the value of this will also be different in the setInterval() callback than the value you want so the one you want is saved here in self so it can be referenced from that. There's also no need to use .apply() in this case because calling a method on an object will automatically set the this pointer as needed.

Categories