avoiding setTimeOut loop multiple instances - javascript

I have a function like so:
https://jsfiddle.net/pjngaffo/1/
i=0;
function refreshInfos() {
if($('.main_dialog').length > 0) {
console.log('loop-->',i++);
setTimeout(function(){refreshManager()},1000);
}
}
$('.main_dialog').on('click',function(){
refreshInfos();
});
function refreshManager(){
//do stuff
//then call refreshInfos() for automatisation purposes
refreshInfos();
}
As you can see, if I click on the button "click -> console" there is multiple instances of the function refreshInfos().
My question is, how can I call that function (anywhere I'll need it) to makes the other instances stop/destroy?

As #priyadarshi swain answered you need to use clearTimeout()
1st: save setTimeout() to the global variable to allow you to clear the timer later
2nd: create another function to stop the timer and reset the i variable to 0 as well
3rd: you'll need to always call the stop timer function before run timer function
Here's how you can do this
var i = 0 , timer = 0; // set timer as a global variable
function refreshInfos() {
if($('.main_dialog').length > 0) {
console.log('loop-->',i++);
timer = setTimeout(function(){refreshManager()},1000); // save it to timer variable
}
}
// another function to stop the timer
function StoprefreshInfos(){
clearTimeout(timer); // clear the timer
i = 0; // reset i variable to 0
}
$('.main_dialog').on('click',function(){
StoprefreshInfos(); // run the stop timer function before refresh info function
refreshInfos(); // then run the refresh info function
});
// button click to just test and stop the timer
$('.stop').on('click',function(){
StoprefreshInfos(); // stop the timer function
});
function refreshManager(){
//do stuff
//then call refreshInfos() for automatisation purposes
refreshInfos();
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div class='main_dialog' style="border:1px solid #333">
click -> console
</div>
<div class='main_dialog' style="border:1px solid #333">
click -> console
</div>
<button class="stop">Stop Timer</button>
Note: while refreshInfos(); run inside refreshManager() and you're using setTimeout(function(){refreshManager()},1000); this
code will refresh the refreshInfos(); so I didn't find a good way to
clear the timer inside the refreshInfos(); function .. and instead I
create another function to stop the timer

Use window.clearTimeout() to stop excution.
var timeout = setTimeout(function(){refreshManager()},1000);
window.clearTimeout(timeout);

Related

clearInterval not working in javascript chrome extension

I'm trying to make a chrome extension and in my content script which runs only on www.youtube.com it's supposed to check, document.getElementById("movie_player"), if a particular div element has loaded or not. If not setInterval and wait a second. If it has loaded then run alert("Hello") and clearInterval which will end the script.
However, it's not working. Even after I find the element, and it says "Hello" it continues to say hello which means setInterval is still calling my function after 1000 milliseconds even though it should have been cleared.
Here's my content.js file:
var timeOut;
function CheckDOMChange()
{
moviePlayer = document.getElementById("movie_player");
if(moviePlayer !== null)
{
WhenVideoLoads();
}
timeOut = setInterval("CheckDOMChange();", 1000);
}
function WhenVideoLoads()
{
alert("Hello");
clearInterval(timeOut);
}
CheckDOMChange();
As you can see, I made timeOut a global variable so it shouldn't be a scope problem. So I really don't know what the problem is because the condition is being met and clearInterval is being called.
Any help would be much appreciated.
The issue is that you have setInterval inside the function. Basically, for every call you are setting interval which creates multiple setIntervals. Remove the setInterval from within the function
var timeOut;
function CheckDOMChange() {
moviePlayer = document.getElementById("movie_player");
if (moviePlayer !== null) {
WhenVideoLoads();
}
}
function WhenVideoLoads() {
alert("Hello");
clearInterval(timeOut);
}
timeOut = setInterval("CheckDOMChange();", 1000);
By calling CheckDOMChange recursively, you are actually exponentially creating timers, and you are only clearing the last timer when calling WhenVideoLoads.
You may try to run this snippet and inspect the console to see what is happening, and see that clicking the button will clear the last timer but not all those that have been created before.
var timeOut;
var counter = 0;
function CheckDOMChange()
{
console.log("counter :", counter);
if (counter > 16) {
console.log("Stop creating new timers!");
return;
}
timeOut = setInterval("CheckDOMChange();", 5000);
console.log("timeOut :", timeOut);
counter ++;
}
function WhenVideoLoads()
{
console.log("Clearing ", timeOut);
clearInterval(timeOut);
}
CheckDOMChange();
<button onclick="WhenVideoLoads()" id="clear">Clear timer</button>
You should avoid calling CheckDOMChange recursively, and proceed as #cdoshi suggested.
Hope this helps!

Boolean statement not evaluating in javascript

I'm writing a script, and there are two boolean statements that are very similar but giving different results, and I don't see why they conflict with one another.
My function looks like this:
SCRIPT:
(function() {
window.onload = function() {
let stopped = true;
let button = document.getElementById("start-stop");
if (stopped) {
setInterval(function() {
console.log("The timer is working.");
}, 1000);
}
button.addEventListener('click', function(){
if (stopped) {
stopped = false;
console.log(stopped);
} else {
stopped = true;
console.log(stopped);
}
});
}
}
}).call(this);
The basic idea is that when I push the button the setInterval function stops, however it keeps on going even when the if/else function switches stopped to false.
For example, my console.log looks like this:
I.e. stopped = false, but setInterval doesn't terminate.
Why is this not evaluating correctly?
The problem with your code is that you are trying to work on a piece of code that has already started to operate. In simpler words, the setInterval method will be called every 1000ms, no matter what the value of stopped variable is. If you wish to really stop the log, you can do any of these:
clearInterval()
to completely remove the interval or
setInterval(function() {
if (stopped) {
console.log("The timer is working.");
}
}, 1000);
to check if the value of stopped variable has changed or not (after the click) and act accordingly. Choose either of these for your purpose..
you are calling setinterval even before button is clicked .As the event is already triggered you cannot stop just by setting the variable to false ,you need to clear the interval using clearinterval
check the following snippet
var intervalId;
window.onload = function() {
let stopped = true;
let button = document.getElementById("start-stop");
var Interval_id;
button.addEventListener('click', function() {
if (stopped) {
Interval_id = callTimeout();
stopped = false;
} else {
clearInterval(Interval_id);
stopped = true;
}
});
}
function callTimeout() {
intervalId = setInterval(function() {
console.log("The timer is working.");
}, 1000);
return intervalId;
}
<input type="button" id="start-stop" value="click it">
Hope it helps
Put the if(stopped) statement inside the setInterval function because if you used this function once it will keep going..
Another way to stop setInterval function is by using clearInterval, like this
var intervalId = setInterval(function() { /* code here */}, 1000)
// And whenever you want to stop it
clearInterval(intervalId);
When you click the button stopped variable becomes false but the setInterval will not stop because the setInterval code is already executed.. it will not execute again on button click. And if you reload the page what will happen is that stopped variable will be again set to true as you have written at first line and setInterval will execute again ..
Now What you can do is store setInterval in a variable like this
var timer = setInterval(function,1000);
and then when you click the button use this method to clear interval
clearInterval(timer);
this should do the trick .. Hope it helps ..

Execute Multiple Clicks

I am trying to click a button multiple times. Each time the button is clicked, it loads for 1 second, reappears and is able to be clicked again. I want to click this button 5 times.
for(i=0;i<5;i++)
$('.class').click();
The above code only executes one click.
Even this code, execute only one click.
for(i=0;i<5;i++)
setTimeout(() => $('.class').click(),2000);
If I do the step manually , that is if I enter $('.class').click() to the console five times, it works. Any idea as to why ?
Multiply the delay with the i since for loop does not wait for executing the setTimeout callback.
for(i = 1;i <= 5; i++)
setTimeout(() => $('.class').click(),i * 2000);
Another way is to use setInterval method along with clearInterval.
// variable for count
var i = 0;
// reference for clearing interval
var inter = setInterval(()=>{
// trigger click event
$('.class').click();
// increment and check value reached to `5`
// if `5` then clear the interval
if(++i == 5) clearInterval(inter);
},2000);
If you log the click event on button, it is clicked 5 times, even with your first example
$('.button').on('click', function () {
console.log('clicked')
})
for(i=0;i<5;i++)
$('.button').click();
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<button class="button"></button>

checking for active timer (setTimeout)

I have a function that contain setTimeout() Method.
I have a button that calls that function, so you could hit this button multiple times and call this function as many times as you want.
Is there a way to actually execute this function, only if there is no other instance of this function that has an active timer?
You would have to keep track of whether you had previously set this timer or not and whether it was still active by using some sort of variable that had a scope that persisted across multiple button presses.
There is no built-in function that will tell you whether the timer you started with this button is still running. You have to create your own. It could work something like this:
var buttonTimer;
function myButtonClick() {
if (!buttonTimer) {
buttonTimer = setTimeout(function() {
buttonTimer = null;
// put your timer code here
}, 2000);
}
}
This will ignore the button click as long as there is a currently active timer. When there is no timer running, it will set a new timer.
Because you're keeping track of the actual timer ID, you have the freedom to implement other behaviors too such as cancelling the previous timer (such as a stop button) or reset the timer to a new time interval by cancelling the previous timer and then setting a new one.
Try this:
var Timer = function() {
var self = this;
this.running = false;
this.run = function() {
if(!self.running) {
self.running = true;
console.log('starting run');
setTimeout(function() {
self.running = false;
console.log('done running!');
}, 5000);
} else {
console.log('i was running already!');
}
}
return this;
}
var aTimer = new Timer();
And add a button for testing purposes:
<button onclick="aTimer.run()">Run!</button>
Fiddle: http://jsfiddle.net/kukiwon/FCuNh/

setInterval again in 5 seconds after clearInterval button

I'm doing a content slider that automatically cycles slides (by periodically calling the "next" function using setInterval)but stops when the user click on a prev/next buttons (by using clearInterval on the prev/next buttons). Is there a way to use setInterval again after a few seconds of clicking the button?
Code:
// start to automatically cycle slides
var cycleTimer = setInterval(function () {
$scroll.trigger('next');
}, 450);
// set next/previous buttons as clearInterval triggers
var $stopTriggers = $('img.right').add('img.left'); // left right
// function to stop auto-cycle
function stopCycle() {
clearInterval(cycleTimer);
}
Put your setInterval in a function and then call that function with setTimeout().
The difference between setInterval() and setTimeout() is that setInterval() calls your function repeatedly at each interval, while setTimeout() calls your function only once after the specified delay.
In the code below I've added a function startCycle(). Call that function to, well, start the cycle, both immediately so that it starts automatically and from a timeout set within your existing stopCycle() function.
var cycleTimer;
function startCycle() {
cycleTimer = setInterval(function () {
$scroll.trigger('next');
}, 450);
}
// start to automatically cycle slides
startCycle();
// set next/previous buttons as clearInterval triggers
var $stopTriggers = $('img.right').add('img.left'); // left right
// function to stop auto-cycle
function stopCycle() {
clearInterval(cycleTimer);
setTimeout(startCycle, 5000); // restart after 5 seconds
}

Categories