I have this function.
function changeFrame(){
var time = setInterval(start, 250);
}
and I want to stop it from firing in another function, but haven't been able to figure out how to do it.
Do you mean this?
function changeFrame(){
var time = setInterval(function() {
// Do stuff
}, 250);
}
Think it's in the comments.
Ok amended the fiddle to do what you want. I made time a global var. Call clearInterval in stop with the global var http://jsfiddle.net/QNWF4/3/
In order to call clearInterval you need to have the handle returned by setInterval. That means something will either be global to the page or global to a containing function in which your script resides.
function Timer()
{
var handle = null;
this.start = function (fn,interval) {
handle = setInterval(fn,interval);
};
this.stop = function ()
{
if (handle) { clearInterval(handle); handle = null; }
};
return this;
}
Related
I'm trying to cancel a requestAnimationFrame loop, but I can't do it because each time requestAnimationFrame is called, a new timer ID is returned, but I only have access to the return value of the first call to requestAnimationFrame.
Specifically, my code is like this, which I don't think is entirely uncommon:
function animate(elem) {
var step = function (timestamp) {
//Do some stuff here.
if (progressedTime < totalTime) {
return requestAnimationFrame(step); //This return value seems useless.
}
};
return requestAnimationFrame(step);
}
//Elsewhere in the code, not in the global namespace.
var timerId = animate(elem);
//A second or two later, before the animation is over.
cancelAnimationFrame(timerId); //Doesn't work!
Because all subsequent calls to requestAnimationFrame are within the step function, I don't have access to the returned timer ID in the event that I want to call cancelAnimationFrame.
Looking at the way Mozilla (and apparently others do it), it looks like they declare a global variable in their code (myReq in the Mozilla code), and then assign the return value of each call to requestAnimationFrame to that variable so that it can be used any time for cancelAnimationFrame.
Is there any way to do this without declaring a global variable?
Thank you.
It doesn't need to be a global variable; it just needs to have scope such that both animate and cancel can access it. I.e. you can encapsulate it. For example, something like this:
var Animation = function(elem) {
var timerID;
var step = function() {
// ...
timerID = requestAnimationFrame(step);
};
return {
start: function() {
timerID = requestAnimationFrame(step);
}
cancel: function() {
cancelAnimationFrame(timerID);
}
};
})();
var animation = new Animation(elem);
animation.start();
animation.cancel();
timerID; // error, not global.
EDIT: You don't need to code it every time - that's why we are doing programming, after all, to abstract stuff that repeats so we don't need to do it ourselves. :)
var Animation = function(step) {
var timerID;
var innerStep = function(timestamp) {
step(timestamp);
timerID = requestAnimationFrame(innerStep);
};
return {
start: function() {
timerID = requestAnimationFrame(innerStep);
}
cancel: function() {
cancelAnimationFrame(timerID);
}
};
})();
var animation1 = new Animation(function(timestamp) {
// do something with elem1
});
var animation2 = new Animation(function(timestamp) {
// do something with elem2
});
I have a function that will continuously reset every time a button is clicked, however, I am trying to clear that timer when a certain picture is on the screen. There are more things going on in the program but this is the general problem I am having. Here is what I have so far:
JavaScript:
function reset() {
var f = document.getElementById("ff").onclick;
var ft = setTimeout(function(){ dontf() }, 3000);
f = ft;
}
function dontf() {
document.getElementById("r").src="H.jpg";
}
function s() {
if (document.getElementById("r").src == "file:///C:/Users/S.jpg") {
clearTimeout(ft);
}
}
HTML
<button onclick="reset(); s();" id="ff">Fd</button>
You can look at this mate
All you needed to do is define var ft in a scope which is accessible by both of the dontf and s funtion
let timer;
function reset() {
const element = document.getElementById("resetButton");
timer = setTimeout(function(){ addImageFunc() }, 3000);
}
function addImageFunc() {
console.log(timer); document.getElementById("addImage").src="https://images.pexels.com/photos/248797/pexels-photo-248797.jpeg?auto=compress&cs=tinysrgb&h=350";
}
function stopReset() {
if (document.getElementById("addImage").src == "https://images.pexels.com/photos/248797/pexels-photo-248797.jpeg?auto=compress&cs=tinysrgb&h=350") {
clearTimeout(timer);
}
}
<html>
<body>
<button onclick="reset(); stopReset();" id="resetButton">Fd</button>
<img id='addImage'>
</body>
</html>
Suggestions
Use proper naming convention for the variables and functions which will make your code more readable and easy debugging.
Don't use var. use let or const.
Try avoid using global scope variables unless there is no alternate way.
The scope of ft is unreachable since it is defined inside of a function. Need to move it to a scope where the other method is able to reference it.
var ft; // define it outside
function reset() {
// var f = document.getElementById("ff").onclick; <<-- no clue what this is doing
if (ft) window.clearTimeout(ft); // if it is running, remove it
ft = setTimeout(dontf, 3000);
// f = ft; <-- does not make sense
}
function dontf() {
document.getElementById("r").src="H.jpg";
}
function s() {
if (document.getElementById("r").src == "file:///C:/Users/S.jpg") {
if (ft) clearTimeout(ft);
}
}
I need to clear an interval from another function
window.onload = function(){
var interval = null;
interval = setInterval(function(){
myFunction();
}, 1000);
function stop(){
clearInterval(interval);
}
}
without pass the interval variable
stop();
But I cannot make it working: when I call stop(); the interval continues...
How can I do?
There is an unexpected window.stop function which preexists yours.
That's another proof that global variables/functions are evil.
It might be this function which gets invoked instead of yours, depending on when the script is loaded.
Try to put your function in an object to protect namespaces:
It works in the StackOverflow fiddle:
var i = 0;
function myFunction() {
i++;
console.log(i);
}
var interval = null;
interval = setInterval(function() {
myFunction();
}, 1000);
var myObject = {
stop: function() {
console.log("stopping");
clearInterval(interval);
}
};
<button onclick="myObject.stop();">stop</button>
In the faulty jsFiddle, you get things in iframes, meaning window element is not the same. That's why your function is not invoked. That gives you that kind of errors:
You can put your script in the html to get it working:
jsfiddle
You could simply put something like var interval = null; at the beginning of the JavaScript outside of a function.
It's all about variable scope. A variable defined inside of a function is only available within that function. A variable defined outside of a function or object will be available globally to all functions.
What is the scope of variables in JavaScript?
I found also this solution working:
stop = function(){
clearInterval(interval);
}
The presumption on the answer you've checked as solution is wrong.
Your stop function wouldn't be working regardless of the fact that there are browsers supporting load stop command programmatically.
This [stop] command is a window property and can be deleted and\or be overwritten by a simple variable declaration or by a function with the same name anywhere on the script.
The reason you are not being able to call the stop function ( from the outside ), is because it's a closure.
Regards.
p.s.:
throwing it up on global scope will make it work, visit you fiddle
var i=0;
function myFunction(){
i++;
$('i').html(i);
}
interval = null;
interval = setInterval(function(){
myFunction();
}, 100);
stop = function(){
clearInterval(interval);
}
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();
I'm trying to cancel a requestAnimationFrame loop, but I can't do it because each time requestAnimationFrame is called, a new timer ID is returned, but I only have access to the return value of the first call to requestAnimationFrame.
Specifically, my code is like this, which I don't think is entirely uncommon:
function animate(elem) {
var step = function (timestamp) {
//Do some stuff here.
if (progressedTime < totalTime) {
return requestAnimationFrame(step); //This return value seems useless.
}
};
return requestAnimationFrame(step);
}
//Elsewhere in the code, not in the global namespace.
var timerId = animate(elem);
//A second or two later, before the animation is over.
cancelAnimationFrame(timerId); //Doesn't work!
Because all subsequent calls to requestAnimationFrame are within the step function, I don't have access to the returned timer ID in the event that I want to call cancelAnimationFrame.
Looking at the way Mozilla (and apparently others do it), it looks like they declare a global variable in their code (myReq in the Mozilla code), and then assign the return value of each call to requestAnimationFrame to that variable so that it can be used any time for cancelAnimationFrame.
Is there any way to do this without declaring a global variable?
Thank you.
It doesn't need to be a global variable; it just needs to have scope such that both animate and cancel can access it. I.e. you can encapsulate it. For example, something like this:
var Animation = function(elem) {
var timerID;
var step = function() {
// ...
timerID = requestAnimationFrame(step);
};
return {
start: function() {
timerID = requestAnimationFrame(step);
}
cancel: function() {
cancelAnimationFrame(timerID);
}
};
})();
var animation = new Animation(elem);
animation.start();
animation.cancel();
timerID; // error, not global.
EDIT: You don't need to code it every time - that's why we are doing programming, after all, to abstract stuff that repeats so we don't need to do it ourselves. :)
var Animation = function(step) {
var timerID;
var innerStep = function(timestamp) {
step(timestamp);
timerID = requestAnimationFrame(innerStep);
};
return {
start: function() {
timerID = requestAnimationFrame(innerStep);
}
cancel: function() {
cancelAnimationFrame(timerID);
}
};
})();
var animation1 = new Animation(function(timestamp) {
// do something with elem1
});
var animation2 = new Animation(function(timestamp) {
// do something with elem2
});