In javascript, if you set a variable to the interval, and clear it, is there a way to turn it back on? Thanks. If you need code, please ask. I have tried just putting the interval name, but that returns a number. I have also tried putting it as a function, which returns an error.
var on = false;
var time = 0
function toggle() {
if (on === false) {
start()
on = true
} else {
stop()
on = false
}
}
function start() {
var interval = window.setInterval(function() {
add()
}, 1000)
console.log('1')
}
function stop() {
clearInterval(interval);
console.log('2')
}
function add() {
time = time + 1;
document.getElementById('time').innerHTML = time;
}
<div id='time'></div>
<button onClick="toggle()">Toggle</button>
Move your code that starts the setInterval into a function.
Clear the interval and then call the function again.
Once you clear an interval you cannoy restart it.
I don't think you need to clear and set again interval.
How about this approach:
var start = document.getElementById('start')
var stop = document.getElementById('stop')
var time = document.getElementById('time')
var isRunning = false
start.onclick = function() {
isRunning = true
}
stop.onclick = function() {
isRunning = false
}
function func() {
if (isRunning) {
time.innerHTML = +time.innerHTML + 1
}
}
setInterval(func, 1000)
<button id="start">start</button>
<button id="stop">stop</button>
<div id="time">0</div>
your code already supports the functionality you are asking for. you are just not stopping the interval as sabithpocker mentioned because of the interval variable scope. just use start() whenever you want to continue. since the add() function is using a global variable time then it won't matter if you stopped it and wanted it to recreate the interval later. also I enhanced the toggle flag assignment a bit.
I also recommend reducing the number of defined functions. you can put all this logic into one function or inject it from the caller for more dynamicity.
var on = false,interval;
var time = 0
function toggle() {
on=!on;
if (on == true) {
start();
} else {
stop();
}
}
function start() {
interval = window.setInterval(function() {
add()
}, 1000)
console.log('1')
}
function stop() {
clearInterval(interval);
console.log('2')
}
function add() {
time = time + 1;
document.getElementById('time').innerHTML = time;
}
<div id='time'></div>
<button onClick="toggle()">Toggle</button>
Related
function tick() {
seconds_lapsed++; // Break point.
}
function countdown() {
while(!stopped || !is_paused()){
setTimeout(tick, 1000); // 1 second.
show_counter();
}
}
Could you tell me why the interpreter doesn't stop at the breakpoint? The while loop works, hava a look at the screenshot.
The while loop is a "busy" loop, i.e. it keeps the JavaScript engine busy, so it will not process anything that is waiting in one of its event/job queues. This means that the user interface does not get updated, no input can be processed, and events produced by setTimeout are not consumed. In this example, tick can only get executed if the currently running code finishes. So the while loop must end first.
You should let tick execute, and only then check the condition:
var stopped = true;
var seconds_lapsed = 0;
document.querySelector("button").addEventListener("click", function() {
stopped = !stopped;
seconds_lapsed = 0;
this.textContent = stopped ? "Start" : "Stop";
if (!stopped) countdown();
});
function show_counter() {
document.querySelector("span").textContent = seconds_lapsed;
}
function is_paused() {
return document.querySelector("input").checked;
}
function tick() {
seconds_lapsed++;
}
function countdown() {
show_counter();
setTimeout(function () {
if (stopped) return; // stop the loop
if (!is_paused()) tick();
countdown(); // <--- this is the "loop"
}, 1000);
}
Seconds elapsed: <span>0</span><br>
<input type="checkbox">Paused<br>
<button>Start</button>
the following example might help you accomplish what you are after. Distinguish between setInterval() and setTimeout()
Basically the docs say:
setTimeout executes a function or specified piece of code once the timer expires.
setInterval repeatedly calls a function or executes a code snippet, with a fixed time delay between each call.
So if you use setInterval you don't need a while loop inside because it is already called "repeatedly"
var counter = $('#counter');
var stopped = false;
var seconds_lapsed=0;
var myInterval;
function tick() {
if(stopped) {
clearInterval(myInterval);
show_counter('FINISHED');
return;
}
show_counter(seconds_lapsed++);
}
function show_counter(message){
counter.html(message);
}
function countdown() {
myInterval = setInterval(tick, 1000);
}
function endCountdown(timeout) {
let timeoutId = setTimeout(function(){
stopped = true;
clearTimeout(timeoutId)
}, timeout);
}
countdown(); // start the countdown
endCountdown(5000); // ends the countdown after 5000 ms => 5sec
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<div id="counter">counter</div>
Cannot terminate the setInterval I created in launch. It works until the time is up. I want to use clearInterval (interval) operation in next() function and prev() function. How should I do this? When I click forward, I want clearInterval(interval) to run this, but I couldn't.
function launch() {
thisTimeline = document.getElementsByClassName('story-active-' + start)[0];
var maxtime = 5000;
var incremental = 100;
var actualtime = 0;
var interval = setInterval(function() {
actualtime += incremental;
var percentage = Math.ceil((100 / maxtime) * actualtime);
thisTimeline.style.width = percentage + '%';
if (percentage == 100) {
clearInterval(interval);
thisTimeline.style.width = "0%";
}
}, incremental);
}
function next() {
// Set previous video timeline to 100% complete
thisTimeline.style.width = '100%';
// Advance play count to next video
start++;
// If next video doesn't exist (i.e. the previous video was the last) then close the Social Story popup
if (start >= defaults.playlist.length) {
setTimeout(function() {
close();
return false;
}, 400);
} else {
// Otherwise run the next video
launch(start);
}
}
function prev() {
if (start != 0) {
thisTimeline.style.width = '0%';
}
// Subtract play count to previous video
start--;
// If next video doesn't exist (i.e. the previous video was the last) then close the Social Story popup
if (start < 0) {
start = 0;
return false;
} else {
// Otherwise run the previous video
launch(start);
}
}
This is an extension of #lagoCalazans comment.
What he is saying is that in your variable "interval" is created in your launch function. You need to make "interval" global in order to clear your setInterval.
Ex:
let interval = null; //global
function launch() {
let tempInterval = setInterval(function() {
//whatever code
},100);
interval = setInterval(function(){
console.log("Hello");
}, 100);
}
function clear() {
//Since interval is global I can clear it when I call clear();
clearInterval(interval);
}
As you can see in the launch function "tempInterval" is limited to the scope of launch, therefore cannot be accessed anywhere else, but now since "interval" is global it can be accessed in any function.
Your code seems a bit incomplete, so for illustrative purposes only I will assume you encapsulate those functions in a higher order function (like an IIFE) and will avoid writing that (also, some kind of global state or variable would do for an example).
First of all, setInterval will return an id which you would use later, so if you want to use it within next and prev, you need that value to be available to them.
So, in your example, you should declare interval outside launch, and assign a value to it inside:
let interval
function launch() {
// ...
interval = setInterval(function() { ... })
}
and then use interval wherever you want.
launch, next and prev are three separate functions. They do not reference the same interval because they don't share scope. Raise the scope of the interval variable.
let interval = ''; // declared here, interval can be accessed by all functions
function launch() {
// ...
// remove the var before interval
interval = setInterval( ... )
}
function next() {
// ...
// remove the var before interval
interval = setInterval( ... )
}
function prev() {
// ...
// remove the var before interval
interval = setInterval( ... )
}
I was recently making a timer object and a ticking function that would tick every second according to a setTimeout loop. However, there was no delay in the ticking. If you try out the below code, you will find that the time number has increased to the thousands in only a few seconds. What, if anything, am I doing wrong?
<html>
<head>
</head>
<button onclick="startTimer()">Start</button>
<button onclick="stopTimer()">Stop Timer</button>
<button onclick="readTimer()">Read Timer</button>
<script>
function tick(){
console.log("TICK TOCK");
if(this.running == true){
this.time += 1;
console.log("HELLO!");
setTimeout(this.tick(), 1000, $(this));
}
}
function start(){
this.running = true;
this.tick();
}
function read(){
return this.time;
}
function stop(){
this.running = false;
}
function reset(){
if(this.running == false){
this.time = 0;
}else {
this.time = 0;
}
this.tick();
}
function timer(){
this.running = false;
this.time = 0;
this.start = start;
this.read = read;
this.stop = stop;
this.reset = reset;
this.tick = tick;
}
var t = new timer();
function startTimer(){
t.start();
}
function stopTimer(){
t.stop();
}
function readTimer(){
alert("This is the current Timer Reading: " + t.time);
}
</script>
</html>
Your error is that you call setTimeOut on this.tick(). When you call this inside the tick() function, you are already referring to the tick function, so you want to use setTimeout(this, 1000); and your timer will work properly.
See this fiddle for solution: https://jsfiddle.net/sg7yf6r4/
Read more about the issue: Javascript objects calling function from itself
The first parameter of setTimeout should be a function. However, you are passing it the result of a function. So instead of setTimeout(this.tick(), 1000, $(this)); you should use setTimeout(this.tick, 1000, $(this));.
You are passing an executed function, instead of a function reference to setTimeout. To pass the function itself, remove the parentheses. Secondly, to make sure this will still be the current this when tick is eventually invoked, use .bind(this).
Note that the third argument of setTimeout would pass that value to tick, which is of no use in your case. NB: That $(this) is probably a remnant of some other code, since the $ would be typically used with jQuery, which you are not using.
So taking that all together, do:
setTimeout(this.tick.bind(this), 1000)
I know this question has been answered before, but none of the other answers seemed to quite solve my problem. I have a timer function that, on invocation, should use setInterval to run every second for 5 seconds and then stop. This works once, but clearInterval doesn't seem to be working, since the second half of the countdown loop keeps running. I feel like this is a scope error, but I've tried moving setInterval and clearInterval outside the function with no luck. Here's my code - this function is called on a button click:
var startGame = function(){
var count = 5;
var countdownTimer = function(){
setInterval(countdown, 1000);
};
var countdown = function(){
if (count > 0){
console.log('inside counter loop');
count--;
$('.timer').text('0:' + count);
} else {
clearInterval(countdownTimer);
console.log('inside endGame loop');
//endgame(); //This should run once when the timer reaches 0.
}
};
countdownTimer();
};
Right now, the loop will run correctly once, and then console.log 'inside endGame loop' every second without resetting. I want the loop to run once, stop, and then wait to be restarted until the on click handler calls the function again.
setInterval() returns the interval id you need to store it and use that with clearInterval()
var startGame = function() {
var count = 5;
var intervalID ;
var countdownTimer = function() {
//Store the intervalID
intervalID = setInterval(countdown, 1000);
};
var countdown = function() {
if (count > 0) {
console.log('inside counter loop');
count--;
$('.timer').text('0:' + count);
} else {
if (intervalID) {
//Pass currect pointer
clearInterval(intervalID);
}
}
};
countdownTimer();
};
For instance, I am setting an interval like
timer = setInterval(fncName, 1000);
and if i go and do
clearInterval(timer);
it does clear the interval but is there a way to check that it cleared the interval? I've tried getting the value of it while it has an interval and when it doesn't but they both just seem to be numbers.
There is no direct way to do what you are looking for. Instead, you could set timer to false every time you call clearInterval:
// Start timer
var timer = setInterval(fncName, 1000);
// End timer
clearInterval(timer);
timer = false;
Now, timer will either be false or have a value at a given time, so you can simply check with
if (timer)
...
If you want to encapsulate this in a class:
function Interval(fn, time) {
var timer = false;
this.start = function () {
if (!this.isRunning())
timer = setInterval(fn, time);
};
this.stop = function () {
clearInterval(timer);
timer = false;
};
this.isRunning = function () {
return timer !== false;
};
}
var i = new Interval(fncName, 1000);
i.start();
if (i.isRunning())
// ...
i.stop();
The return values from setTimeout and setInterval are completely opaque values. You can't derive any meaning from them; the only use for them is to pass back to clearTimeout and clearInterval.
There is no function to test whether a value corresponds to an active timeout/interval, sorry! If you wanted a timer whose status you could check, you'd have to create your own wrapper functions that remembered what the set/clear state was.
I did this like below, My problem was solved. you should set the value like "false", when you clearTimeout the timer.
var timeer=false;
----
----
if(timeer==false)
{
starttimer();
}
-----
-----
function starttimer()
{
timeer_main=setInterval(activefunction, 1000);
timeer=true;
}
function pausetimer()
{
clearTimeout(timeer_main);
timeer=false;
}
Well you can do
var interval = setInterval(function() {}, 1000);
interval = clearInterval(interval);
if (typeof interval === 'undefined'){
...
}
but what are you actually trying to do? clearInterval function is an always success function and it will always return undefined even if you call it with a NaN value, no error checking in there.
You COULD override the setInterval method and add the capability to keep track of your intervals. Here is an untestet example to outline the idea. It will work on the current window only (if you have multiple, you could change this with the help of the prototype object) and this will only work if you override the functions BEFORE any functions that you care of keeping track about are registered:
var oldSetInterval = window.setInterval;
var oldClearInterval = window.clearInterval;
window.setInterval = function(func, time)
{
var id = oldSetInterval(func, time);
window.intervals.push(id);
return id;
}
window.intervals = [];
window.clearInterval = function(id)
{
for(int i = 0; i < window.setInterval.intervals; ++i)
if (window.setInterval.intervals[i] == id)
{
window.setInterval.intervals.splice(i, 1);
}
oldClearInterval(id);
}
window.isIntervalRegistered(id)
{
for(int i = 0; i < window.setInterval.intervals; ++i)
if (window.setInterval.intervals[i] == func)
return true;
return false;
}
var i = 0;
var refreshLoop = setInterval(function(){
i++;
}, 250);
if (isIntervalRegistered(refrshLoop)) alert('still registered');
else alert('not registered');
clearInterval(refreshLoop);
if (isIntervalRegistered(refrshLoop)) alert('still registered');
else alert('not registered');
The solution to this problem: Create a global counter that is incremented within your code performed by setInterval. Then before you recall setInterval, test if the counter is STILL incrementing. If so, your setInterval is still active. If not, you're good to go.