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/
Related
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 ..
I want to create a timer in JavaScript. I see the setTimeout(fn, 100) but unclear how to wrap this so it will clear itself at the end.
I tried doing
var buttonTimer = null;
$scope.backButton = function() {
if(buttonTimer === null){
$history.back();
}
buttonTimer = setTimeout(function(buttonTimer){
buttonTimer = null;
}, 100);
}
The whole point is to prevent the user from hitting this function too quickly.. and ignoring all subsequent clicks within that 100ms window, at the end of the window, clear the timer and resume accepting clicks
Since you are doing angular, I prepared a plnkr for demonstration:
http://plnkr.co/edit/5qrslKpmkglXTvEyYgBr?p=preview
Your code is almost Ok, the only problem is that you start a new timeout on every click. The effect is, that the callback fires multiple times and resets buttonTimer.
So the only change is:
var blocker = null;
$scope.backButton = function() {
if(blocker == null) {
blocker = setTimeout(function(){
blocker = null;
}, 1500);
// DO YOUR STUFF HERE
}
};
You can use throttle from lodash/underscore or Ramdajs.
for example
$scope.backButton=_.throttle(100,function(){/* do something here */});
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 an input field, and it has a keyup event:
$(document).ready(function() {
$('#SearchInputBox').keyup(function() {
DoSearch($(this).val());
});
});
How can I add a delay time, so that only when the user stopped typing for 1 second, then it will run the DoSearch function. I don't want to keep running it every time the user types a key because if they type fast, then it will lag.
Basically, set a timeout on each keyup. If there's already a timeout running, clear it and set another. The DoSearch() function will only run when the timeout is allowed to complete without being reset by another keyup (i.e., when the user has stopped typing for 1000ms).
var timeout = null;
$('#SearchInputBox').on('keyup', function () {
var that = this;
if (timeout !== null) {
clearTimeout(timeout);
}
timeout = setTimeout(function () {
DoSearch($(that).val());
}, 1000);
});
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);