I am trying to build a countdown that switches between play time and work time. It starts with 10 seconds of work then when it reaches 0 seconds we clear the interval and set it to 'play' and call the function again...
var model = {
intervalID: 0,
status: 'work',
workSeconds: 10,
playSeconds: 10,
}
function startCountdown(){
if (model.status === 'work') {
model.countdown = model.workSeconds;
model.intervalID = setInterval(function(){
model.countdown--;
if (model.countdown > 0) {
console.log('work', model.countdown);
} else {
model.status = 'play';
clearInterval(model.indervalId);
startCountdown();
}
}, 1000);
} else if (model.status === 'play') {
model.countdown = model.playSeconds;
model.intervalID = setInterval(function(){
model.countdown--;
if (model.countdown > 0) {
console.log('play', model.countdown);
} else {
model.status = 'work';
clearInterval(model.indervalId);
startCountdown();
}
}, 1000);
}
}
startCountdown();
This function is supposed to console log a 10 second countdown for work, then when the countdown reaches 0 switch to a 10 seconds countdown of play, and keep doing that.
At the moment it looks like no intervals are being cleared and both intervals just keep setting each other in a feedback loop.
Why are the intervals not being cleared?
I think you have a typo. clearInterval(model.indervalId); should be clearInterval(model.intervalID);.
I'd use setTimeout for this too, but I guess you already know about that.
Related
I made an online quiz application using Vue in which each question has its own duration. I'm using watcher for the countdown and show it on the webpage. The problem I'm facing is every time I updated the time to match the next question's time, the countdown will end much sooner. What can I do to update the time limit in the watcher without interrupting the current countdown?
watch: {
timerEnabled(value) {
if (value) {
setTimeout(() => {
this.timeLimit--;
}, 1000);
}
},
timeLimit: {
handler(value) {
if (value >= 0 && this.timerEnabled) {
setTimeout(() => {
this.timeLimit--;
}, 1000);
}
else{
// set the timer to the next question's time limit and move to the next question
}
}
}
}
I think you can try something like this:
data() {
return {
timer: null,
timerCounter: 0
}
},
methods: {
setTimer(state) { // true enabled, false disabled
if(state) {
this.timerCount = // seconds
this.timer = setTimeout(() => {
timerCounter--;
if(timerCounter <= 0) {
this.setTimer(false);
// go to next question
this.setTimer(true);
}
}, 1000);
} else {
clearTimeout(this.timer);
}
}
}
You only need to call setTimer(true) for start the timer for the first time, for example in the mounted() function or at click event of a button.
If you don't want that the timer restart after question change, remove this.setTimer(true);.
How can I restart Interval after clearing it? I want a button to be clickable once every 11 seconds I made it disabled while timer is > 0 after it's equal to 0 button isn't disabled so it's clickable I wrote this code it seems to work but after multiple call of a setInterval() function timer goes down too fast any soltuions>
data:{
sTimer:11,
sDisabled:true,
asd:null
},
methods:{
testing(){
this.sTimer--;
if(this.sTimer == 0){
clearInterval(this.asd);
this.sTimer= 11;
this.sDisabled = false;
}else{
this.sDisabled = true;
}
},
specialAttack(){
setInterval(() => this.testing(), 1000)
}
},
created(){
this.asd = setInterval(() => this.testing(), 1000);
}
<button class="specialAttack" :disabled="sDisabled" #click="specialAttack(); testing()">Special Attack {{ sTimer }}</button>
There are several mistakes you made here, so first of all to achieve such a thing you should use setTimeout instead of setInterval because interval generally will be repeated after a certain given time, so this may one of the possible reason for being called twice when you click your button as well. Then you need to create a generic function for this cause and then call it in document creation instead of creating two different intervals and calling them separately.
So with respecting these rules, your final code should be something like this:
HTML
<button class="specialAttack" :disabled="sDisabled" #click="specialAttack();">Special Attack {{ sTimer }}</button>
Javascript
data: () => {
return {
sTimer: 11,
sDisabled: false,
asd: null
};
},
methods: {
specialAttack() {
clearTimeout(this.asd); // Or as you suggest in comments you can disbale it here with replacing this: this.sDisabled = true
if (this.sTimer > 0) {
this.asd = setTimeout(() => {
this.sDisabled = true;
this.sTimer -= 1;
this.specialAttack();
}, 1000);
} else {
clearTimeout(this.asd);
this.sTimer = 11;
this.sDisabled = false;
}
}
},
created() {
this.specialAttack();
}
Here is a working demo:
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!
Please See the below code runs at the rate of 60 frame per second..If any button is clicked isjump will be set to true and below code start excuting.What i am trying is i need to exit out jump() function after 1 second.I tried setout like below...but still lines inside settime out is running indefinitely..Please help me.
What i am actually trying is exit jump function after 1 second.
function jump() {
if (isjump) {
player.posx +=10;
console.log("jumping"); //this line is stopped after 1 second
setTimeout(function () {
isjump = false;
console.log("stopped"); //but this line is continuing
}, 1000);
}
}
I also tried clearTimeout still no use.
var timeoutHandle = window.setTimeout(function () {
isjump = false;
console.log("stopped");
clearTimeout(timeoutHandle);
}, 500);
Edit : For those who think this jump function is called continously...yea it is called continously...For every frame game character position will be updated.
Ok I found The solution..I solved it by running the settimeout function only once inside a loop.
var once = true;
function jump() {
if (isjump) {
player.posx +=10;
console.log("jumping"); //this line is stopped after 1 second
if(once)
{
setTimeout(function () {
isjump = false;
console.log("stopped"); //but this line is continuing
}, 1000);
}
once = false;
}
}
I have this function:
var secondsRemaining = 45;
function countdown(secondsRemaining) {
var seconds = secondsRemaining;
if (secondsRemaining > 0) {
$('.timer > div').html(seconds);
secondsRemaining--;
} else {
if (secondsRemaining == 0) {
// Times up ....
}
}
setInterval(function() {
countdown(secondsRemaining);
}, 1000);
}
I am running the function in the Document ready function with:
countdown(secondsRemaining);
and also I run it again after I clicked for answer.
the problem is that I have 2 countdown timer now running simultaneously, new one that start from 45 seconds and the old one that continue from where it was.
Use clearInterval()
First, store the interval id of the first setInterval():
var secondsRemaining = 45;
function countdown(secondsRemaining) {
var seconds = secondsRemaining;
if (secondsRemaining > 0) {
$('.timer > div').html(seconds);
secondsRemaining--;
} else {
if (secondsRemaining == 0) {
// Times up ....
}
}
myinterval=setInterval(function() { //myint now contains the interval id
countdown(secondsRemaining);
}, 1000);
}
Now, when the user clicks, before setting up a new interval, cancel the first one with clearInterval():
button.onclick=function(){
//do stuff
clearInterval(myinterval)
setInterval(function() {
countdown(secondsRemaining);
}, 1000);
// do stuff
}
Sorry I don't really understand the way you have phrased the question seems to say that you intentionally want to start two time events, one when the document has loaded and the other when you click answer which are both outputting to the same element.
If the problem is you want it to have the output in two different elements then you could pass an argument of the element you could use:
countdown($('.pick-me'), secondsRemaining);
If you want to use the same element, then you could always clear the interval on each click and then set the interval for the new event, just got the update and seen Manishearths response so wont go into any more detail about it as that's probably the answer you are looking for.