clearInterval not working in javascript chrome extension - javascript

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!

Related

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 ..

ClearInterval function doesn't work in my case

function active_timer(){
var time = 5000;
interval = setInterval(function(){
console.log('interval');
},time);
}
active_timer();
socket.on('timer', function (data) {
console.log('here') // it triggered
clearInterval(interval); // don't work
active_timer() //resume
});
I tried this and it won't work because the console.log still triggered every 5 sec. Any clue why?
Your code is technically running correctly but your console logs are misleading.
You've started an interval which triggers every 5 seconds. Each time your socket even fires, you clear the interval but then immediately start a new one. This gives the illusion that there's no gap in the intervals, but there is.
You can test this by changing your console.log('interval') to console.log(interval). So instead of just printing "interval", it will print out the value of the variable referencing the interval object. This is represented by a number which will change each time the interval is stopped and restarted.
Just to be clear, an interval cannot be resumed, only new ones started and existing ones stopped.
var interval = null;
function startTimer() {
// store the reference to our interval
interval = setInterval(function() {
console.log('triggered interval', interval);
}, 2000);
console.log('new interval started', interval);
}
startTimer();
// button click to simulate your socket event
$('#simulate').on('click', function() {
console.log('received simulated event');
clearInterval(interval);
startTimer();
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<button id="simulate">Simulate Socket Event</button>

Button to refresh page every second/minute etc?

I'm wanting a button that when clicked will refresh the current page after a specified amount of time.
I currently have:
<script type="text/javascript">
setTimeout(function reload(){
location = ''
},1000)
</script>
<button onclick="reload()">Reload</button>
However, that JUST reloads the page without even having to click the button. I'm wanting the button to execute the script, and also a button to STOP the page reload.
This should be really simple but I can't figure it out :(
******EDIT**********
I'd also like the script to run on an infinite loop after the button is clicked.
Your setTimeout is called on page load. You need to put it inside the reload() function:
function reload() {
setTimeout(function() {
window.location.reload();
}, 1000);
}
To make the timer run every x seconds and reload only a part of the page you would need to use setInterval and an AJAX request, something like this:
var timer;
function reload() {
timer = setInterval(function() {
$.post('foo.html', function(data) {
$('#bar').html(data);
});
}, 1000);
}
function clear() {
clearInterval(timer);
}
This should do the trick
<script type="text/javascript">
function reload(){
setTimeout(function(){location.reload()}, 3000);
}
</script>
<button onclick="reload()">Reload</button>
What you wrote is
window.setTimeout("location = ''"; ,1000);
You were saying execute this function after 1 second. You need to define the setTimeout inside the function. Also there is a built in method to reload the page. Call that instead of setting the location to a blank string.
function reload() {
setTimeout( function() {
window.location.reload(true);
},1000);
}
Now to cancel the timeout, you need to use clearTimeout(timeoutId); You get the timeoutId from the integer that the setTimeout returns when you call it.
var timer = null;
function reload() {
timer = window.setTimeout( function() {
window.location.reload(true);
},1000);
}
function cancelReload() {
if (timer) {
window.clearTimeout(timer);
}
timer = null;
}
AND you said you want it to keep running. That will require cookies or localstorage.
var timer = null;
function reload() {
localStorage.reload = true; //set localstorage so we know to fire it off again
timer = window.setTimeout( function() {
window.location.reload(true);
},1000);
}
function cancelReload() {
if (timer) {
window.clearTimeout(timer);
}
timer = null;
localStorage.removeItem("reload"); //remove the key in localstorage
}
if (localstorage.reload) { //check localstorage to see if key is set
reload();
}
You need to wrap the whole thing in another function and call that from the button click

how can I rearrange this code so my setInterval stops looping infinitely?

I'm trying to make a simple flip-card/memory match (like from super mario brothers 3) game in HTML/Javascript and am having a slight issue with the setInterval command.
Here is a link to the full code: http://jsfiddle.net/msfZj/
Here is the main issue/main logic of it:
if(click == 2) //denotes two cards being clicked
{
if(flippedArray[1].src === flippedArray[0].src) // if click 1 == click 2 then refer to function 'delayMatch' which sets click 1 and 2 cards to not be displayed
{
window.setInterval(function() { delayMatch() }, 500);
console.log("EQUAL");
}
else
{
window.setInterval(function() { delayNoMatch() }, 500); // if click 1 != click 2 then display card.png
console.log("NOT EQUAL");
}
function delayMatch() //function for matching pairs
{
flippedArray[0].style = "display:none;";
flippedArray[1].style = "display:none;";
}
function delayNoMatch() //function for non-matching pairs
{
flippedArray[0].src = "card.png";
flippedArray[1].src = "card.png";
}
click = 0; // when clicked two cards set click back to zero
}
The first two cards I click on always work: but from that point onward the setInterval keeps running the function over and over again in an endless loop every 500ms.
I'd be extremely appreciative if anybody can point my in the right direction on how I can do this properly.
Thank you very much for your time.
It looks like you need setTimeout, which only runs once?
window.setTimeout(function() { delayMatch() }, 500);
Otherwise, you need to clear the interval with clearInterval(i), but first set "i" using the return value of setInterval:
var i = window.setInterval(function() { delayMatch() }, 500);
Here's a demo (I JQuerified it a bit for JSFiddle).
You're going to want to go with setTimeout() instead of setInterval()
A handy function when you use setTimeout is clearTimeout. Say you want to set a timer, but maybe want a button to cancel
var timer = setTimeout(fn,1000);
//later maybe
clearTimeout(timer);

Clear Interval not working ( Tried all other answers )

So I have this function to check when a opponent is connected. Everything works, except the clearInterval thing... I tried adding window.setInterval and window.clearInterval . I tried adding self. too...
$(document).ready(function() {
var waitForOpponent = setInterval(checkUserStatus, 2000);
function checkUserStatus() {
$('#user').load('checkuser.php?randval='+ Math.random());
$("#user").ajaxStop(function(){
if(document.getElementById("user").innerHTML!=""){
clearInterval(waitForOpponent);
opponentConnected();
}
});
}
});
I also tried to go like this:
var waitForOpponent;
function check() { waitForOpponent = setInterval(checkUserStatus, 2000); }
check();
Please help me out guys.. I tried everything...
Get rid of ajaxStop and use the success callback of the .load.
$('#user').load('checkuser.php?randval='+ Math.random(),function(){
if(document.getElementById("user").innerHTML!=""){
clearInterval(waitForOpponent);
opponentConnected();
}
});
if the requests are taking longer than 2 seconds, ajaxstop will never be called.
A better alternative in my opinion is to not use setInterval:
function checkUserStatus() {
$('#user').load('checkuser.php?randval='+ Math.random(),function(){
if(document.getElementById("user").innerHTML!=""){
opponentConnected();
return; // exit
}
setTimeout(checkUserStatus,2000); // continue after 2 seconds
});
}
checkUserStatus(); // start it up
this prevents the ajax requests from piling up on slow connections or on timeouts.

Categories