Why clearInterval is not stopping setInterval? - javascript

I'm trying to make a Timer for a project that record audios and while on the making, I've faced with this problem: setInterval is not stopping, why?
I have the following code:
/** Audio **/
var timerseconds = 0;
$('.audio-recorder-dialog-con').on('click', '#record', function() {
gotrecordval = document.getElementById("record").value;
//Crónometro
var timerseconds = setInterval(function() {
rseconds = parseInt(document.getElementById("r-seconds").value);
if (rseconds == 59) {
document.getElementById("r-seconds").value = "00";
}
rseconds = parseInt(document.getElementById("r-seconds").value);
rseconds += 1;
if (rseconds < 10) {
document.getElementById("r-seconds").value = ("00" + rseconds).substr(-2);
}
if (rseconds >= 10) {
document.getElementById("r-seconds").value = rseconds;
}
}, 1000);
//
if (gotrecordval == "Empezar a Grabar Audio") {
document.getElementById("record").value = "Detener/Subir";
}
if (gotrecordval == "Detener/Subir") {
document.getElementById("record").value = "Empezar a Grabar Audio";
$('.audio-recorder-dialog-con').fadeOut(500);
$(".contenido-dialog-new-d").fadeIn(500);
$("#aviaudio").fadeIn(500);
clearInterval(timerseconds);
}
});
--FIXED--
I've fixed it by adding this inside the setInterval:
//Crónometro
var timerseconds = setInterval(function(){
rseconds = parseInt(document.getElementById("r-seconds").value);
if(rseconds==59){document.getElementById("r-seconds").value = "00";}
rseconds = parseInt(document.getElementById("r-seconds").value);
rseconds+=1;
if(rseconds<10){document.getElementById("r-seconds").value = ("00" + rseconds).substr(-2);}
if(rseconds>=10){document.getElementById("r-seconds").value = rseconds;}
--Code added-
$('html, body').on('click', '.open-audio', function(){
clearInterval(timerseconds);
});
--
}, 1000);
//
".open-audio" is an image that opens the recording dialog for the user, so when you re-open it, the clearInterval works.

The solution you added to your question is not sound: this will create a new event handler at every 'tick' of the setInterval timer. That is not the right way to do it.
Instead, only execute setInterval in the case you need to start it, so put it inside the first if:
if (gotrecordval == "Empezar a Grabar Audio") {
//Crónometro
var timerseconds = setInterval(function() {
rseconds = parseInt(document.getElementById("r-seconds").value);
if (rseconds == 59) {
document.getElementById("r-seconds").value = "00";
}
rseconds = parseInt(document.getElementById("r-seconds").value);
rseconds += 1;
if (rseconds < 10) {
document.getElementById("r-seconds").value = ("00" + rseconds).substr(-2);
}
if (rseconds >= 10) {
document.getElementById("r-seconds").value = rseconds;
}
}, 1000);
//
document.getElementById("record").value = "Detener/Subir";
}

Related

JQuery - How to update variable after call function?

I have a timer function, I want to change the value of my variable after the timer reaches 0?
function countdown(minutes) {
var seconds = 60;
var mins = minutes
function tick() {
var counter = document.getElementById("timer");
current_minutes = mins - 1
seconds--;
counter.innerHTML =
current_minutes.toString() + ":" + (seconds < 10 ? "0" : "") + String(seconds);
if (parseInt(current_minutes) === 0 && parseInt(seconds) === 00) {
sendAgain.show();
finalMin = parseInt(current_minutes);
finalSec = parseInt(seconds);
}
if (seconds > 0) {
timeoutHandle = setTimeout(tick, 1000);
} else {
if (mins > 1) {
// countdown(mins-1); never reach “00″ issue solved:Contributed by Victor Streithorst
setTimeout(function () { countdown(mins - 1); }, 1000);
}
}
}
tick();
}
variables :
let finalMin = null;
var finalSec = null;
I want the variables to be set after the following code is executed?
if (parseInt(current_minutes) === 0 && parseInt(seconds) === 00) {
sendAgain.show();
finalMin = parseInt(current_minutes);
finalSec = parseInt(seconds);
}
countdown(2);
console.log(finalMin); ===== show "0"

Javascript setInterval flickering

I'm trying to create a chess clock using JavaScript. I've settle almost all of the issues with the clock's functionality except for this one. I'm using setInterval to essentially create the "countdown" effect on each player's clock. However, when it is triggered with the method I'm currently using the clock flickers. From my understanding/research, this is likely because there are overlapping 'intervals' that cause the code to try to display multiple intervals at the same time. Essentially the clock buttons (stopclock and stopclock2) when clicked call the functions on the bottom of my code. Could anyone provide some input on my code (below) and why this might be occurring?
clear1mils = "";
clear2mils = "";
//Clock Functions
function countdownmils2() {
document.getElementById("milsvalue2").innerHTML = --mil2;
if (mil2 == 0) {
mil2 = mil2 + 59;
if (sec2 == 0) {
if (min2 == 0) {
clearInterval(clear2mils);
document.getElementById("milsvalue2").innerHTML = "00";
}else if (min2 !== 0) {
sec2 = 60;
document.getElementById("minutesvalue2").innerHTML = --min2;
document.getElementById("secondsvalue2").innerHTML = --sec2;
}
}else if (sec2 !== 0) {
document.getElementById("secondsvalue2").innerHTML = --sec2;
if (sec2 <= 10) {
document.getElementById("secondsvalue2").innerHTML = "0" + sec2;
}
}
}else if (mil2 <= 10) {
document.getElementById("milsvalue2").innerHTML = "0" + mil2;
}
}
function countdownmils() {
document.getElementById("milsvalue").innerHTML = --mil;
if (mil == 0) {
mil = mil + 59;
if (sec == 0) {
if (min == 0) {
clearInterval(clear1mils);
document.getElementById("milsvalue").innerHTML = "00";
}else if (min !== 0) {
sec = 60;
document.getElementById("minutesvalue").innerHTML = --min;
document.getElementById("secondsvalue").innerHTML = --sec;
}
}else if (sec !== 0) {
document.getElementById("secondsvalue").innerHTML = --sec;
if (sec <= 10) {
document.getElementById("secondsvalue").innerHTML = "0" + sec;
}
}
}else if (mil <= 10) {
document.getElementById("milsvalue").innerHTML = "0" + mil;
}
}
//Clock 1
document.querySelector("#stopclock").addEventListener("click", () => {
clear2mils = setInterval(countdownmils2, 10);
clearInterval(clear1mils);
document.getElementById("stopclock").innerHTML = "DOWN";
document.getElementById("stopclock2").innerHTML = "UP";
document.getElementById("stopclock").setAttribute("disabled", "true");
document.getElementById("stopclock2").removeAttribute("disabled", "true");
});
//Clock 2
document.querySelector("#stopclock2").addEventListener("click", () => {
clear1mils = setInterval(countdownmils, 10);
clearInterval(clear2mils);
document.getElementById("stopclock2").innerHTML = "DOWN";
document.getElementById("stopclock").innerHTML = "UP";
document.getElementById("stopclock2").setAttribute("disabled", "true");
document.getElementById("stopclock").removeAttribute("disabled", "true");
});

Having issue resetting JS stopwatch

I made a little typing game that reveals some random text and you have to type the same in, so that you can test your typing speed. the users has the ability to play again and again, the issue is that when the user types play again, the stopwatch does not begin as it did the first time.
Can anyone help me with making the stopwatch restart everytime the user clicks on the play again button?
[ full code is here] (https://jsfiddle.net/kisho/ncbxd9o4/#&togetherjs=qD5bT8vLiw)
js portion-
const textDisplay = document.querySelector('#text-display');
const input = document.querySelector('#input');
const btn = document.querySelector('#btn');
const textBox = document.querySelector('#text-box');
const countdown = document.querySelector('#countdown');
const stopwatch = document.querySelector('#stopwatch');
const successMessege = document.querySelector('#success-messege');
const stopwatchTime = document.querySelector('#stopwatch-time');
btn.addEventListener('click', runGame);
function runGame() {
if ((btn.innerText = 'Play again')) {
playAgain();
fetchQuote();
countownTimer();
confirmQuote();
} else {
fetchQuote();
countownTimer();
confirmQuote();
}
}
function fetchQuote() {
fetch('https://api.quotable.io/random')
.then((res) => {
return res.json();
})
.then((data) => {
textDisplay.innerText = data.content;
});
}
function countownTimer() {
if (timer !== undefined) {
clearInterval(timer);
}
var timeleft = 2;
var downloadTimer = setInterval(function() {
if (timeleft <= 0) {
clearInterval(downloadTimer);
document.getElementById('countdown').innerHTML = 'Start Typing!';
input.classList.remove('displayNone');
runningStopwatch.classList.remove('displayNone');
begin();
} else {
document.getElementById('countdown').innerHTML = timeleft + ' seconds remaining';
}
timeleft -= 1;
}, 1000);
}
function confirmQuote() {
if ((countdown.innerHTML = 'Start typing!')) {
input.addEventListener('keyup', function(event) {
if (event.keyCode === 13) {
if (textDisplay.innerText === input.value) {
btn.innerText = 'Play again';
// textBox.classList.add('displayNone');
hold();
} else successMessege.innerText = 'Missed something there, try again!!';
}
});
}
}
function playAgain() {
textBox.classList.remove('displayNone');
input.classList.add('displayNone');
input;
input.value = '';
successMessege.innerText = '';
}
let ms = 0,
s = 0,
m = 0;
let timer;
let runningStopwatch = document.querySelector('.running-stopwatch');
function begin() {
timer = setInterval(run, 10);
}
function run() {
runningStopwatch.textContent =
(m < 10 ? '0' + m : m) + ': ' + (s < 10 ? '0' + s : s) + ': ' + (ms < 10 ? '0' + ms : ms);
ms++;
if (ms == 100) {
ms = 0;
s++;
}
if (s == 60) {
s = 0;
m++;
}
}
function hold() {
clearInterval(timer);
successMessege.innerText = `Nice job! You just typed in x seconds!`;
}
function stop() {
(ms = 0), (s = 0), (m = 0);
runningStopwatch.textContent =
(m < 10 ? '0' + m : m) + ': ' + (s < 10 ? '0' + s : s) + ': ' + (ms < 10 ? '0' + ms : ms);
}
You are not handling the clearInterval correctly.
You are clearing the interval only if one ends the game successfully.
My solution would be:
When calling the countownTimer() function, the first thing you should do, is to check if the interval timer is still running.
function countownTimer() {
if (timer !== undefined) {
clearInterval(timer);
}
// [...]
}
The next thing would be, to start the interval every time begin() gets called.
function begin() {
timer = setInterval(run, 10);
}

How can I convert a vanilla JS stop watch to a Angular one?

new to JS and will delete if not allowed. I have got some regular JS code which I have been working with trying to switch this into a controller.
For the given example what would be the most optimised way. I have seen cases with directives, counters and so on however I am thinking this is very complicated for what I am doing. I have so far manage to bind seconds and tens to screen however I am having issues with the $interval for updating, do I require .watch, .promises .then? (sorry for newb question any help would be great)
JS Script
window.onload = function() {
var seconds = 00;
var tens = 00;
var appendTens = document.getElementById("tens");
var appendSeconds = document.getElementById("seconds");
var buttonStart = document.getElementById('button-start');
var buttonStop = document.getElementById('button-stop');
var buttonReset = document.getElementById('button-reset');
var Interval;
buttonStart.onclick = function () {
clearInterval(Interval);
Interval = setInterval(startTimer, 10);
};
buttonStop.onclick = function () {
clearInterval(Interval);
};
buttonReset.onclick = function () {
clearInterval(Interval);
tens = "00";
seconds = "00";
appendTens.innerHTML = tens;
appendSeconds.innerHTML = seconds;
console.log("clear()");
};
function startTimer() {
tens++;
if (tens < 9) {
appendTens.innerHTML = "0" + tens;
}
if (tens > 9) {
appendTens.innerHTML = tens;
}
if (tens > 99) {
console.log("seconds");
seconds++;
appendSeconds.innerHTML = "0" + seconds;
tens = 0;
appendTens.innerHTML = "0" + 0;
}
if (seconds > 9) {
appendSeconds.innerHTML = seconds;
}
}
};
This is how I am binding HTML to the screen
<span id="seconds">{{ seconds+":"+tens }}</span>
I have this set up with a simple $interval loop that updates the seconds and minutes:
angular.module('plunker', []).controller('MainCtrl', function($interval) {
var interval_;
this.seconds = 0;
this.minutes = 0;
this.start = function() {
interval_ = $interval(function() {
this.seconds++;
if(this.seconds > 59) {
this.seconds = 0;
this.minutes++;
}
}.bind(this), 1000)
}
this.stop = function() {
$interval.cancel(interval_)
}
})
.filter('adjustTime', function(){
return function(input) {
if(input < 10) {
return '0' + input;
}
return input;
}
});
I'm a fan of delegation, so I made the filter you see to handle adding the extra 0 if it's less than 10; no need to muck up the $interval logic.
Plnkr

Counting up and down to specified number in order in Javascript

I am trying to get this script to count up to a specified number and back down to a specified number as follows: 19200, 38400, 57600, 76800, 96000, 76800, 57600, 38400, 19200 — repeatedly. So far this is what I have but I cannot seem to make it count down in the order above, it restarts from 19200 again.
$(function() {
var seconds = 19200;
var timerId = setInterval(function() {
seconds = seconds + 19200;
$("#counter").text(seconds);
if (seconds > "76800") {
clearInterval(seconds);
seconds = seconds - "19200";
}
}, 500);
});
A little issue with the logic, the condition
if (seconds > "76800") {
would always try to keep the seconds above 76800.
Rather you would want a flag to track the direction of the count. Check out below:
UPDATED:
Working demo at
JSFiddle
$(function () {
var increment = 19200;
var seconds = increment;
var countUp = true;
var timerId = setInterval(function () {
$("#counter").text(seconds);
if (countUp) {
seconds += increment;
} else {
seconds -= increment;
}
if (countUp && seconds > increment*4) {
countUp = false;
} else if (!countUp && seconds <= increment) {
countUp = true;
}
}, 500);
});
Check the below function
$(function() {
var seconds = 19200;
action = 'add';
var timerId = setInterval(function() {
$("#counter").text(seconds);
if (seconds == 96000) {
action = 'remove';
} else if (seconds == 19200) {
action = 'add'
}
if (action == 'add')
seconds += 19200;
else if (action == 'remove')
seconds -= 19200;
}, 500);
});
I think this is a little more elegant
var increment = 19200,
seconds = increment;
var timer = setInterval(function() {
console.log(seconds);
seconds += increment;
if (seconds > 76800 || seconds < 19200) {
increment *= -1;
}
}, 500);
jsfiddle

Categories