how to make an infinate loop in javascript - javascript

I am just starting in javascript, I would like to have a toggle button that runs a function until it's pressed again. I have some code for the toggle:
const backgroundButton = document.getElementById("backgroundButton"); //getting button from HTML
let clickToggle = 0; //defining a veriable used to store the state of the button
backgroundButton.addEventListener("click", function(){
if (clickToggle == 0) {
console.log('button was off');
//start loop
clickToggle = 1;
}
else {
console.log('button was on');
//stop loop
clickToggle = 0;
}
});
but, I don't know how to do an infinite loop, any help is greatly appreciated!
(PS: I know infinite loops crash, that's why I'm here)

You could use setInterval and clearInterval. A truly infinite loop would look like this:
while (true) doSomething();
But that is not what anyone wants, as it will block the user interface. Using setTimeout or setInterval you allow the event loop to continue to do its work.
I'll assume you want to repeat calling the function doSomething in this demo:
const backgroundButton = document.getElementById("backgroundButton");
let timer = 0;
const output = document.getElementById("output");
backgroundButton.addEventListener("click", function(){
if (timer == 0) {
console.log('button was off');
//start loop
timer = setInterval(doSomething, 50);
}
else {
console.log('button was on');
//stop loop
clearInterval(timer);
timer = 0;
}
});
function doSomething() {
output.textContent = +output.textContent + 1;
}
<button id="backgroundButton">Start/Stop</button>
<div id="output"></div>

You can do something like this. Hopefully following with resolve you're required scenario.
let isEnabled = false;
let interval;
function clickFunction() {
isEnabled = !isEnabled; // toggle enable flag
if (isEnabled) {
console.log('Set Interval', isEnabled)
interval = setInterval(function () {
console.log('Do some work.');
}, 1000);
} else {
console.log('Clear Interval', isEnabled)
clearInterval(interval);
}
}
<button onclick="clickFunction()">Click me</button>

You can also use Window.requestAnimationFrame() for the infinite loop.
const toggleButton = document.querySelector('#toggle');
let hasBegun = false;
let anim;
const tick = () => {
if (hasBegun) {
document.querySelector('#output').textContent += '+';
};
requestAnimationFrame(tick)
};
toggleButton.addEventListener("click", function() {
if (!hasBegun) {
console.log('Starting');
hasBegun = true;
anim = requestAnimationFrame(tick);
} else {
console.log('Stopping');
hasBegun = false;
cancelAnimationFrame(anim);
anim = null;
}
});
<button id="toggle">Start/Stop</button>
<pre id="output"></pre>

Related

Javascript pause/resume toggle button

I am working on a little challenge with school. We have learned CSS, HTML, and Javascript. I am trying to create a timer that is always running in the background. Then I need a button that pauses said timer and changes into a resume button that will resume the timer. This is what I have come up with.
document.addEventListener("DOMContentLoaded", () => {
const counterElement = document.getElementById('counter')
let counterValue = 0
const pauseButton = document.getElementById('pause')
const resumeButton = document.getElementById('resume')
const submitButton = document.getElementById(`submit`)
const minusButton = document.getElementById(`minus`)
const plusButton = document.getElementById('plus')
const heartButton = document.getElementById('heart')
intervalId = setInterval(myCallback, 1000);
function myCallback() {
counterValue += 1;
counterElement.innerHTML = counterValue;
}
function resume() {
setInterval(myCallback, 1000);
pauseButton.style.display = '';
resumeButton.style.display = 'none';
}
function pause() {
clearInterval(intervalId);
pauseButton.style.display = 'none';
resumeButton.style.display = '';
}
pauseButton.addEventListener("click", (e) => {
pause()
})
resumeButton.addEventListener("click", (e) => {
resume()
})
It does not function properly. Only the first few clicks work.
function resume() {
intervalId = setInterval(myCallback, 1000);
pauseButton.style.display = '';
resumeButton.style.display = 'none';
}
Try this. The root issue is that you're not assigning your setInterval reference back to your intervalId variable. So when you call clearInterval(intervalId) later, your code is saying, "That's already been cleared..." and not doing anything.
In short, your current resume() function creates a NEW setInterval - it doesn't update the old one. And since there was no reference to the new setInterval, there was no way for your pause function to be able to find it and clear it.
When you call setTimeout in the resume function, you have to reassign the intervalId variable to store the new interval ID. If you don't do that, your pause function will keep cancelling the first interval, which is a no-op.
So do this instead:
document.addEventListener("DOMContentLoaded", () => {
const counterElement = document.getElementById('counter')
let counterValue = 0
const pauseButton = document.getElementById('pause')
const resumeButton = document.getElementById('resume')
//const submitButton = document.getElementById(`submit`)
//const minusButton = document.getElementById(`minus`)
//const plusButton = document.getElementById('plus')
//const heartButton = document.getElementById('heart')
//It's a good idea to declare your variables. Since you want to reassign it, you probably want `let`.
let intervalId = setInterval(myCallback, 1000);
function myCallback() {
counterValue += 1;
counterElement.innerHTML = counterValue;
}
function resume() {
//Assign the new interval ID to `intervalId`
intervalId = setInterval(myCallback, 1000);
pauseButton.style.display = '';
resumeButton.style.display = 'none';
}
function pause() {
clearInterval(intervalId);
pauseButton.style.display = 'none';
resumeButton.style.display = '';
}
pauseButton.addEventListener("click", (e) => {
pause()
})
resumeButton.addEventListener("click", (e) => {
resume()
})
})
<button id="pause" >Pause</button>
<button id="resume" style="display:none;" >Resume</button>
<div id="counter" >0</div>
When you create a new Interval in your resume() function, you need to store its return value again in your intervalId variable for the next time you call pause().

Counter stop out of the window browser

im trying to create a counter, the problem is that im trying to make the counter run only if the user is in the window, if the user goes out of the window or to another separator the counter should stop untill he comes back.
Here is my code:
$(window).blur(function(){
console.log("Counter Should Stop");
});
$(window).focus(function(){
window.onload = function(){
(function(){
var counter = 10;
setInterval(function() {
counter--;
if (counter >= 0) {
span = document.getElementById("count");
span.innerHTML = counter;
}
// Display 'counter' wherever you want to display it.
if (counter === 0) {
alert('this is where it happens');
clearInterval(counter);
}
}, 1000);
})();
}
});
You've got some scoping issues, as well as nested function issues. For readability, as well as helping you debug, I'd recommend refactoring it into separate function names for each event. This also helps promote reusability.
This should do what you're looking for:
(function(){
// your global variables
var span = document.getElementById("count");
var counter = 10;
var timer;
// your helpers
var startTimer = function() {
// do nothing if timer is already running
if (timer) return;
timer = setInterval(function() {
counter--;
if (counter >= 0) {
span.innerHTML = counter;
}
// Display 'counter' wherever you want to display it.
if (counter === 0) {
alert('this is where it happens');
stopTimer();
}
}, 1000);
};
var stopTimer = function() {
clearInterval(timer);
timer = null;
};
// your handlers
var onBlur = function() {
stopTimer();
};
var onFocus = function() {
startTimer();
};
var onLoad = function() {
startTimer();
};
// assign your handlers
$(window).load(onLoad);
$(window).blur(onBlur);
$(window).focus(onFocus);
})();

Changer SetInterval Values After Interval

If I can try to make everyone understand what I am looking for, I am looking for the value of the interval to change to lets say "5000ms" after "1000ms" and then it would go on to the next value such as "2000ms" and repeat all over again! The current code I have is pretty much a stopwatch, It adds the number 1 to a paragraph every 1000ms. Any help is extremely appreciated!
<script>
function myFunction() {
clicks += 1;
}
setInterval(myFunction, 1000);
var clicks = 0;
function myFunction() {
clicks += 1;
document.getElementById("demo").innerHTML = clicks;
// connects to paragraph id
}
</script>
<p id="demo"></p>
<!--connects to getElementById-->
Don't use setInterval - this functions will perform the action in any given interval, which you set once.
Use setTimeout instead. Which performs the action only once after given interval, and then call it again and again with different interval values.
what about this
<script>
var clicks = 0;
myFunction(1000);
function myFunction( currentInterval ) {
clicks ++;
document.getElementById("demo").innerHTML = clicks;
if ( currentInterval == 1000 )
{
currentInterval = 5000;
}
else if ( currentInterval == 5000 )
{
currentInterval = 2000;
}
else
{
currentInterval = 1000;
}
setTimeout( function(){ myFunction( currentInterval ) }, currentInterval );
}
</script>
<p id="demo"></p>
you should try using recursive timeout instead of interval
var timeout = 1000;
var timer;
function startTimer() {
clearTimeout(timer);
timer = setTimeout(function() {
console.log('tick');
startTimer();
}, timeout);
}
startTimer();
// timeout = 2000
// timeout = 500
// clearTimeout(timer); to cancel
<script src="https://getfirebug.com/firebug-lite-debug.js"></script>
This might look a little complicated but you can try something like this:
JSFiddle.
(function() {
var interval = null;
var limit = 5;
function initInterval(callback, index) {
var msToSec = 1000;
if (interval) {
clearInterval();
}
console.log("Delay: ", index)
interval = setInterval(callback, index * msToSec);
}
function clearInterval() {
window.clearInterval(interval);
interval = null;
}
function resetInterval(callback, count) {
clearInterval();
initInterval(callback, count);
}
function main() {
var count = 1;
var notify = function() {
console.log("Hello World: ", count);
var _nextCount = ((count++) % limit) + 1;
if (count < 10) {
resetInterval(notify, _nextCount);
} else {
console.log("Stoping loop...");
clearInterval();
}
}
initInterval(notify, count);
}
main()
})()

Stop countdown on click

I want my countdown to stop on the click of a submit button, i searched in some pages,
but I didn't found anything.
Here is the code i want to stop on click
function countDown (count) {
if (count > 0) {
var d = document.getElementById("countDiv");
d.innerHTML = count;
setTimeout (function() { countDown(count-1); }, 1000);
document.getElementById('tiempo').value = count;
}
else
document.location = "timeover.php";
}
document.getElementById("palabra").focus();
countDown(5);
</script>
You have to save reference to timeout (actually return value of timeout will be number) and use it to cancel timeout.
var timeout = window.setTimeout(function () {
// do something
}, 1000);
// clear timeout
window.clearTimeout(timeout);
You probably got the idea. By the way, you should probably look at setInterval method since it would be better in this situation. Interval will "tick" as long until you cancel it.
Try something like this:
var stopped = false;
function countDown (count) {
if (count > 0) {
var d = document.getElementById("countDiv");
d.innerHTML = count;
document.getElementById('tiempo').value = count;
if (!stopped) {
setTimeout (function() { countDown(count-1); }, 1000);
}
}
else
document.location = "timeover.php";
}
document.getElementById("palabra").focus();
document.getElementById("mySubmitId").onclick = function () {
stopped = true;
};
countDown(5);

How would I toggle the state of a setInterval function in jQuery?

I want to be able to click a an element with an id of pause to start a count of the elements in a time object and if I re click the pause it will stop it and reclick start it exactly like the toggle feature in JQuery but with a setInteval function how would I go about doing this?
$("#pause").click(function(ffe) {
if(on == true) {
on = false
alert("on");
}
else {
on = true;
alert("off");
}
if(on == false) {
setInterval(function() {
$("#timet ul").append("<li>" + $("#time ul")
.children('li').length +"</li>");
}, 100);
}
else {
alert("Error");
}
});
A classic technique is to use a single master setInterval loop and simply use if..else logic to determine what needs to run. This is how a lot of javascript games work:
var on = true;
// Our master scheduler:
setInterval(function() {
if (on) {
$("#timet ul").append("<li>" + $("#time ul")
.children('li').length +"</li>");
}
}, 100);
// Code to handle the pause button
$("#pause").click(function(ffe) {
on = !on;
}
You can use the setTimeout function, if you want to run the function once, setInterval runs continuously, try the following:
var on = false;
$("#pause").click(function(ffe) {
if (on) {
on = false;
setTimeout(function() {
$("#timet ul").append("<li>" + $("#time ul")
.children('li').length +"</li>");
}, 100);
} else {
on = true;
}
});
You need to use .clearInterval() to stop the execution.
Here is the code: (THE WORKING DEMO)
$("#pause").click((function () {
var interId = null;
var $ul = $("#timet ul");
return function (e) {
if (interId) {
$(this).text("start");
clearInterval(interId);
interId = null;
} else {
$(this).text("pause");
interId = setInterval(function () {
$ul.append($('<li>').text($('li', $ul).length));
}, 100);
}
};
}()));​

Categories

Resources