I want to detect a change in the value of Date().getSeconds() as soon as it happens.
I currently use:
function updateClock {
....
}
function detectChange(previousSec) {
var currentSec = new Date().getSeconds();
if (previousSec !== currentSec) {
updateClock();
}
}
setInterval(function () {
var dat = new Date();
var sec = dat.getSeconds;
detectChange(sec);
}, 10);
Is there a better way to do this?
Thanks!
How about a 2-step process?
First, align your clock with the system's 0-millisecond mark
setTimeout(startClock, 1000 - (new Date()).getMilliseconds());
Then, you only need to tick once per second
function startClock() {
setInterval(function do_your_thing() { ... }, 1000);
}
Practical demonstration (jsfiddle) shows that even if you do a large amount of work during the cycle, this method is pretty stable. In fact, on my machine you get better precision than the ±16ms resolution typically achievable in desktop task schedulers.
Unfortunately there is no standard event that fires when the clock changes seconds, so you'll need to set up an interval to detect it.
Setting an interval for every 1000ms means your clock could be off by almost a full second. Therefore I can understand why you'd want to check the seconds more than just once per second. The core concept here is sampling rate. The faster we sample the more precise we are, but the more processing time we waste detecting changes.
I think this will work for you.
function updateClock (date) {
console.log(date);
};
(function () {
var oldDate = new Date();
return setInterval(function () {
var date = new Date();
if (date.getSeconds() != oldDate.getSeconds()) {
updateClock(date);
}
oldDate = date;
}, 10); // precision is ~10ms
})();
It will have a new value after every one second, therefore just put a timer with 1 second interval.
Related
I'm quite a newbie, so forgive my ignorance. I am trying to, through local storage, get a timer to tell the user when they last visited the page. But I have instead made an infinite loop, how do I correct this? calling the function outside the function? What would this look like?
$(document).ready(function(){
var myDate = new Date(2015,4,9,0,0);
localStorage["mydate"] = JSON.stringify(myDate);
startTimer();
});
function startTimer() {
setInterval(function(){
var text = "It's been " + hoursSinceFirstVisit() + " hours since you first visited.";
$('#timer').text(text);
}, 1000);
}
function hoursSinceFirstVisit() {
var currentDate = new Date();
var lastDate = new Date(JSON.parse(localStorage["mydate"]));
return hoursBetweenDates( lastDate, currentDate);
}
<div id="timer"></div>
Thanks!
There is no hoursBetweenDates function provided, so I added one. For debugging recursion errors, try moving the anonymous function to a named function as it is called repeatedly. Break code into smaller parts and make sure no part repeatedly calls itself:
$(document).ready(function() {
var myDate = new Date(2015, 4, 9, 0, 0);
localStorage.mydate = JSON.stringify(myDate);
function startTimer() {
setInterval(updateMessage, 100);
}
function updateMessage() {
var text = "It's been " + hoursSinceFirstVisit() + " hours since you first visited.";
$('#timer').text(text);
}
// This is my function for getting hours between dates
function hoursBetweenDates(d1, d2) {
return Math.abs(d1 - d2) / 36e5;
// For integer hours use this function
// return Math.floor(Math.abs(d1 - d2) / 36e5);
}
function hoursSinceFirstVisit() {
var currentDate = new Date();
var lastDate = new Date(JSON.parse(localStorage.mydate));
return hoursBetweenDates(lastDate, currentDate);
}
startTimer();
});
This will work fine without recursion errors. Here is a demo. Note, I made it return hours with decimal precision since the last visit, and set the interval to 100 ms to demonstrate it works fine. Update your version as you like. Apologies, I could not make a Stack Snippet because local storage is disabled.
Demo: http://jsbin.com/demevi/3/
The function setInterval() schedules a function to be executed repeatedly, waiting a specified number of milliseconds before each run.
If you want to delay the execution of function hoursSinceFirstVisit() (and run it only once) then you have to use setTimeout():
function startTimer() {
setTimeout(function() {
var text = "It's been " + hoursSinceFirstVisit() + " hours since you first visited.";
$('#timer').text(text);
}, 1000);
}
I am trying to "cache" some information by storing it in a variable.
If 2 minutes have passed I want to get the "live" values (call the url).
If 2 minutes have not passed I want to get the data from the variable.
What I basicly want is:
if(time passed is less than 2 minutes) {
get from variable
} else {
get from url
set the time (for checking if 2 minutes have passed)
}
I've tried calculating the time with things like
if((currentime + 2) < futuretime)
but it wouldn't work for me.
Anybody know how to properly check if 2 minutes have passed since the last executing of the code?
TL;DR: Want to check if 2 minutes have passed with an IF statement.
Turning your algorithm into working javascript, you could do something like this:
var lastTime = 0;
if ( Math.floor((new Date() - lastTime)/60000) < 2 ) {
// get from variable
} else {
// get from url
lastTime = new Date();
}
You could put the if block in a function, and call it anytime you want to get the info from either the variable or the url:
var lastTime = 0;
function getInfo() {
if ( Math.floor((new Date() - lastTime)/60000) < 2 ) {
// get from variable
} else {
// get from url
lastTime = new Date();
}
}
Hope it helps.
If you want to do something on a timer in JavaScript, you should be using setTimeout or setInterval.
Having your code run in a continuous loop will cause your browser's VM to crash.
Using setTimeout is rather easy:
setTimeout(function(){
// do everything you want to do
}, 1000*60*2);
This will cause the function to run in at least two minutes from the time the timeout is set(see this blog post from John Resig for more deatils). The second argument is the number of milliseconds, so we multiply by 60 to get minutes, and then 2 to get 2 minutes.
setInterval, which follows the same syntax will do something EVERY x milliseconds.
Without using 3rd party libs, just use Date.getTime() and store it as some variable:
var lastRun = null;
function oneIn2Min() {
if (lastRun == null || new Date().getTime() - lastRun > 2000) {
console.log('executed');
}
lastRun = new Date().getTime();
}
oneIn2Min(); // prints 'executed'
oneIn2Min(); // does nothing
oneIn2Min(); // does nothing
setTimeout(oneIn2Min, 2500); // prints 'executed'
You can also opt to make some simple object out of it (to keep your code organised). It could look like this:
var CachedCall = function (minTime, cbk) {
this.cbk = cbk;
this.minTime = minTime;
};
CachedCall.prototype = {
lastRun: null,
invoke: function () {
if (this.lastRun == null || new Date().getTime() - this.lastRun > this.minTime) {
this.cbk();
}
this.lastRun = new Date().getTime();
}
};
// CachedCall which will invoke function if last invocation
// was at least 2000 msec ago
var c = new CachedCall(2000, function () {
console.log('executed');
});
c.invoke(); // prints 'executed'
c.invoke(); // prints nothing
c.invoke(); // prints nothing
setTimeout(function () {c.invoke();}, 2300); // prints 'executed'
If you're open to include 3rd party libs this might be very handy in other tasks too:
http://momentjs.com/docs/#/manipulating/add/
You can do something like that
var myVal = {
data: null,
time: new Date()
}
function getMyVal () {
if(myVal.time < new Date(new Date().getTime() - minutes*1000*60)) {
myVal.data = valFromRequest;
myVal=time=new Date();
}
return myVal.data;
}
I'm trying to call the setInterval function in my pop up window to update the time every second but when it is called my HTML page doesn't update at all just shows the initial time upon loading. I can't see what I'm doing wrong with this code.
var currentTime = new Date();
window.self.setInterval(
function()
{
window.self.document.getElementById("Time").innerHTML = currentTime.toTimeString();
}, 1000 );
Any reason why this is happening?
currentTime is being set once and only once. You need to create a new Date object at every interval. Something like this:
setInterval(
function()
{
document.getElementById("Time").innerHTML = (new Date()).toTimeString();
},
1000
);
So I have this simple HTML:
<span id="badge">0</span>
I want the number 0 to increase by 1 every x milliseconds. How do I do that with Javascript (with or without jQuery)?
Thanks a bunch - I'm new to this :)
You should do this:
<script>
var $badge = $('#badge'); // cache
setInterval(function () {
var value = parseInt($badge.html());
value++;
$badge.html(value);
}, 1000);
</script>
Assuming 1000 milliseconds.
function increment() {
document.getElementById("badge").value = Number(document.getElementById("badge").value) + 1;
setTimeout("increment()",3000);
}
increment()
Every of the answers I see here has the same drawbacks:
performance issue because of selecting the DOM element every ms cycle. Especially when using a heavy library as jQuery.
setInterval() is probably the tool designed for that functionality, but not reliable. It can diverge a lot from the real time, especially when using a small interval. If you want exactly x executions per second, you may google for some timing libraries.
I would code:
var textNode = document.getElementById(badge).firstChild;
var start = Date.now();
window.setInterval(function update() {
textNode.data = Math.round((new Date()-start)/ms);
}, ms);
If you don't want to start at 0, it will be trivial to add an offset (determined before the loop begins), eg.
var start = Date.now() - (textNode.data * ms || 0); // NaN catching, implicit number cast
Something like this?
var millisecs = 10;
setInterval(function() {
var $badge = $('#badge');
$badge.text(parseInt($badge.text())++);
}, millisecs);
http://jsfiddle.net/iambriansreed/MPP8n/3/
Check this http://www.w3schools.com/js/js_timing.asp
A little more about timers:
// setting a variable for your timer will allow you the ability to "turn it on and off"
var tmrChangeI;
// setTimeout is a function to initiate a function once after given amount of milisecs
// whereas setInterval will continue a function until cancled every so many milisecs
// the following wil "turn on" your timer
tmrChangeI = setInterval(function() {
var $badge = $('#badge');
$badge.html($badge.html() + 1);
}, 500); // 500 will = every half of a second
// to "turn off" timer
clearInterval(tmrChangeI);
// or set a bool to test and use timeout to repeat till bool is false
var tmrBool = true;
// establish function to execute
function tmrFunc() {
var $badge = $('#badge');
$badge.html($badge.html() + 1);
if (tmrBool) tmrChangeI = setTimeout(function() { tmrFunc(); }, 500); // 500 will = every half of a second
};
// execute function, begin timer
tmrChangeI = setTimeout(function() { tmrFunc(); }, 500);
// clear via bool allowing one more execution
tmrBool = false;
// clear by force possibly stoping next execution,
// tho in this manner it may be too late if timer is very short
// and maybe overriden by bool still being true, this is not safest
// but is example of how to use setTimeout
clearTimeout(tmrChangeI);
You can use setInterval.
var $badge = $('#badge');
setInterval(function () {
$badge.html(parseInt($badge.html()) + 1);
}, 1);//Specify the milliseconds here, right it will update the value every 1 millisecond
Working demo - http://jsfiddle.net/8FMZh/
You could create a Jquery plugin, so you can reuse whenever you need.
$.fn.increment= function(options) {
var $this = $(this);
var coef = options.coef;
var speed = options.speed;
var value = 0;
setInterval(function(){
value = value + coef ;
$this.html(value);
}, speed);
};
And in your main javascript file :
$("#badge").increment({coef: 1, speed:1000});
working demo : http://jsfiddle.net/8FMZh/102/
var now = new Date();
var millisTill10 = new Date(now.getFullYear(), now.getMonth(), now.getDate(), 1, 20, 00, 0) - now;
function openAPage() {
var startTime = new Date().getTime();
var myWin = window.open("http://google.com","_blank")
var endTime = new Date().getTime();
var timeTaken = endTime-startTime;
document.write("<br>button pressed#</br>")
document.write(startTime);
document.write("<br>page loaded#</br>")
document.write(endTime);
document.write("<br>time taken</br>")
document.write(timeTaken);
myWin.close()
}
function beginSequence() {
openAPage();
setInterval(openAPage, 5000);
}
setTimeout(beginSequence, millisTill10);
This is my JS code. I am opening a web page with setTimeout as you see. But after then I want to put an internal for example I will call openAPage function every 1 minute after setTimeout statement. How will I do it? Can anyone fix my code?
setTimeout(startOpeningPages, millisTill10);
function startOpeningPages() {
openAPage();
setInterval(openAPage, 60 * 1000);
}
I realize there are a lot of correct answers already. I'll post this anyway for kicks :)
function() {
var win = window.open("about:blank")
var doc = win.document
doc.write("Hello")
setTimeout(arguments.callee, 60*1000)
}()
These are 2 of the my favorite things you can do in Javascript: Self-invoke a function (the ending () after the function declaration, and being able to access the anonymous function from within the function through arguments.callee.
This is better than setInterval in that the first process has to be completed and then 60s later, the second process starts. With setInterval, the process just keeps starting every 60s. 60s is a large interval where this wouldn't matter as much, but this usually matters a lot more with smaller times (in the ms ranges). Because it might end up buffering the second function to execute before the first one is complete.