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 ..
Related
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!
I would like to use setInterval to control a refresh of my page. I would like to have it running by default (on when the page loads) but I need to be able to turn it off at certain times. So I've written what you see below. The problem is that the refresh is not on when the page first displays. It only comes on after I click the button twice to re-activate the update the setInterval controls.
My html button definition looks like this;
<button id="autoref" type="button" name="autoref" onclick="stopAutoRef();">Stop Auto Ref</button>
My stopAutoRef function looks like this;
function stopAutoRef() {
if ($("#autoref").text() == "Stop Auto Ref") {
$("#autoref").html('Start Auto Ref'); // You see this if Refresh is not automatically happening
clearInterval();
}else {$("#autoref").html('Stop Auto Ref'); // You see this if Refresh is automatically happening
setInterval(function() {showActivities(document.getElementById("select1").value);}, 60000);
}
}
setInterval returns an ID which must be passed to clearInterval to stop it. You'd also want to call your function, startAutoRef(), immediately in addition to on click to initiate the default behavior of refreshing.
var autoRefId = null;
function stopAutoRef() {
if (autoRefId !== null) {
$("#autoref").html('Start Auto Ref'); // You see this if Refresh is not automatically happening
clearInterval(autoRefId);
autoRefId = null;
} else {
$("#autoref").html('Stop Auto Ref'); // You see this if Refresh is automatically happening
autoRefId = setInterval(function() {showActivities(document.getElementById("select1").value);}, 60000);
}
}
stopAutoRef();
clearinterval generally requires a argument of which function to stop. so try this maybe?
try this:
HTML:
<button id = 'b' onclick = 'stop(this)' value = 'true'>Stop ref</button>
Javascript:
var myfunc = setInterval(function(){
location.reload();
},1000);;
function stop(button){
if(button.innerHTML == 'Stop ref'){
button.innerHTML = 'Start ref';
clearInterval(myfunc);
}
else{
button.innerHTML = 'Stop ref';
myfunc = setInterval(function(){
location.reload();
},1000);;
}
}
I am trying to have my button doing two things.
init a timer to call a function
call the same function
I have something like the following
test.prototype.setupEvent= function(){
var instance = this;
$('#btn').on('click', function(){
clearInterval(instance.timer);
this.showStuff()
instance.timer=setInterval(function(){
instance.showStuff()
},10000);
})
}
test.prototype.showStuff= function(btnID){
//jump to another page
}
My problem is that I want the user be able to see some contents after 10 second when they first click it, however, if they click the button again before 10 second is up, they can see the contents too. I am not sure how to distinguish the two different states with one click event. Can anyone help me out? Thanks!
Try
test.prototype.setupEvent = function () {
var instance = this;
$('#btn').on('click', function () {
//if there is a timer running then clear the timer, show the content and delete the timer reference
if (instance.timer) {
clearInterval(instance.timer);
instance.showStuff();
delete instance.timer
return;
}
//also you may want to use setTimeout() not setInverval()
instance.timer = setInterval(function () {
instance.showStuff();
delete instance.timer
}, 10000);
})
}
test.prototype.showStuff = function (btnID) {
//jump to another page
}
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/
i have a simple question, there is a function with parameter emp_id that opens up a form for a chat with different attributes, i want it to be refreshed automatically each 10 sec, now it works a bit wrongly, since there is a parameter emp_id that is can be changed, and once i change it, the chat with messages and form are refreshed double time or triple times :) depend on how many times u change the emp_id, i hope i was clear )) anyway here is the javascript function:
function load_chat(emp_id) {
var url = "#request.self#?fuseaction=objects2.popup_list_chatform"
url = url + "&employee_id=" + emp_id;
document.getElementById('form_div').style.display = 'block'; AjaxPageLoad(url,'form_div',1,'Yükleniyor');
setInterval( function() {
load_chat(emp_id);
},10000);
}
there a list of names, once i click on one of them, this form is opened by this function, but if i click another user, i mean if i change the emp_id, it refreshes, the previous and present form. how do i change it so that it will refresh only the last emp_id, but not all of id's which i've changed
thank you all for the help, i really appreciate it!
This would nicely encapsulate what you're doing. The timer id (tid) is kept inside the closure, so when you call load_chat it will stop the interval if there was one running.
Once the new url is set up, it will start the interval timer again.
var ChatModule = (function() {
var tid,
url;
function refresh()
{
AjaxPageLoad(url, 'form_div', 1, 'Yükleniyor');
}
return {
load_chat: function(emp_id) {
if (tid) {
clearInterval(tid);
}
// setup url
url = "#request.self#?fuseaction=objects2.popup_list_chatform"
url = url + "&employee_id=" + emp_id;
document.getElementById('form_div').style.display = 'block';
// load ajax
refresh();
// set timer
tid = setInterval(refresh, 10000);
}
}
}());
ChatModule.load_chat(123);
Use setTimeout instead. Each time your function is executed, it will set up the next execution (you could also make it conditional):
function load_chat(emp_id) {
... // do something
if (condition_still_met)
setTimeout(function() {
load_chat(emp_id); // with same id
}, 10000);
}
load_chat("x"); // to start
Or you will have to use setInterval outside the load_chat function. You can clear the interval when necessary.
function get_chat_loader(emp_id) {
return function() {
... // do something
};
}
var id = setInterval(get_chat_loader("x"), 10000); // start
// then, somewhen later:
clearInterval(id);