Log the time in between user - a simple timer - javascript

I'm trying to create a simple timer.
The user presses a 'start' button. When the user presses another button, I would like to log the time in between.
Could this be achieved with setTimeout?

setTimeout shouldn't be used for your situation. The following is a method to display the amount of seconds between clicking "startBtn" and then clicking "endBtn":
var date1 = new Date();
document.getElementById("startBtn").onclick = function(){
date1 = new Date();
}
document.getElementById("endBtn").onclick = function(){
var date2 = new Date();
var dif = date1.getTime() - date2.getTime();
var Seconds_from_T1_to_T2 = dif / 1000;
var Seconds_Between_Dates = Math.abs(Seconds_from_T1_to_T2);
alert(Seconds_Between_Dates);
}
You can build from here to get your desired functionality (for example, if the user clicks "endBtn" before clicking "startBtn", the results are inaccurate, of course. You can fix by disabling buttons as needed, etc.)
(thanks to How Many Seconds Between Two Dates?)

It's really not necessary to use a Timeout for this. All you want to do is measuring two difference between two time dates.
HTML:
<span class="startTimer">
Start Timer
</span>
<span class="stopTimer">
Stop Timer
</span>
<span class="result">
</span>
JS, and no, the use of JQuery is not needed here but I like the way it handles events:
(function($){
var Timer = {
startTimeInMs: null,
endTimeInMs: null,
start: function(){
this.startTimeInMs = new Date();
},
stop: function(){
this.endTimeInMs = new Date();
},
getTime: function(){
return this.endTimeInMs - this.startTimeInMs;
},
bind: function() {
var self = this;
$('.startTimer').on('click', function(){
self.start();
});
$('.stopTimer').on('click', function(){
self.stop();
self.printResult();
});
},
printResult: function() {
$(".result").html(this.getTime())
},
init: function(){
this.bind();
}
}
var timer = Object.create(Timer);
timer.init();
})(jQuery);

You can just use the Date.now() method, there's no need to instantiate a new Date object each time.
Here's a jsFiddle that measures lap times as an example: http://jsfiddle.net/ZpFnp/
HTML
<button id="start">start/reset</button>
<button id="stop">lap</button>
<div id="output"></div>
JavaScript
var startTime = Date.now();
document.getElementById("start").addEventListener("click", function () {
document.getElementById("output").innerHTML = "";
startTime = Date.now();
});
document.getElementById("stop").addEventListener("click", function () {
var elapsedTime = Date.now() - startTime;
document.getElementById("output").innerHTML += "<p>" + elapsedTime + "</p>";
});

Related

Laravel jquery javascript localStorage

Problem is my timer was working as well. But when i save timers value to localStorage. I just want to when user refresh timer wont stop and resume when stopped at.
javascript
function startTimer() {
var presentTime = document.getElementById('timer').innerHTML;
var timeArray = presentTime.split(/[:]+/);
var m = timeArray[0];
var s = checkSecond((timeArray[1] - 1));
if(s==59){m=m-1}
if(m<0){ document.myform.submit(); }
document.getElementById('timer').innerHTML =
m + ":" + s;
setTimeout(startTimer, 1000);
var startTime = document.getElementById("timer").value;
localStorage.setItem("startTime", startTime);
//alert(startTime);
}
function Dahin(){
var startTime = localStorage.getItem("startTime");
document.getElementById('timer').value = startTime;
}
in my view
<h3 onload="Dahin();" class="page-title">Шалгалтын 50 асуулт</h3><h4><div>Үлдсэн хугацаа = <span id="timer">{{ $time }}</span></div></h4>
Update fixed timer
now how to save timer value to sessionstorage and retrieve when refresh page
Let change your code:
var check = localStorage.getItem("startTime");
var startTime = check ? check : document.getElementById("timer").innerHTML;
document.getElementById('timer').value = startTime;
function Dahin(){
localStorage.setItem("startTime", startTime);
}
the problem why you get null is because you use .value. You put your time into span tag. .value is only work for input field

Time Interval seconds run fast on tab changed Javascript

I have an issue that hold my neck with time interval. I am calculating my time/clock one second at a time with the function below.
Header.prototype= {
time_changed : function(time){
var that = this;
var clock_handle;
var clock = $('#gmtclock');
that.time_now = time;
var increase_time_by = function(interval) {
that.time_now += interval;
};
var update_time = function() {
clock.html(moment(that.time_now).utc().format("YYYY-MM-DD HH:mm") + " GMT");
};
update_time();
clearInterval(clock_handle);
clock_handle = setInterval(function() {
increase_time_by(1000);
update_time();
}, 1000);
},
};
The above works fine and increase my time a second at a time correctly . However. I added another event that fires on web changed or tab navigated.
var start_time;
var tabChanged = function() {
if(clock_started === true){
if (document.hidden || document.webkitHidden) {
start_time = moment().valueOf();
time_now = page.header.time_now;
}else {
var tnow = (time_now + (moment().valueOf() - start_time));
page.header.time_changed(tnow);
}
}
};
if (typeof document.webkitHidden !== 'undefined') {
if (document.addEventListener) {
document.addEventListener("webkitvisibilitychange", tabChanged);
}
}
The above fires when ever user leave the page and comes back . It add the delay to the time. However, i notice the second increase rapidly . and very past my timer does not fire very second any more as specified in the clock hand. It add second every milliseconds and fats. Please why this and how do i fix this ? My time run fast and ahead when ever i change tab and returned . Any help would be appreciated
Update
Below is my WS request function.
Header.prototype = {
start_clock_ws : function(){
var that = this;
function init(){
clock_started = true;
WS.send({ "time": 1,"passthrough":{"client_time" : moment().valueOf()}});
}
that.run = function(){
setInterval(init, 900000);
};
init();
that.run();
return;
},
time_counter : function(response){
var that = this;
var clock_handle;
var clock = $('#gmt-clock');
var start_timestamp = response.time;
var pass = response.echo_req.passthrough.client_time;
that.time_now = ((start_timestamp * 1000) + (moment().valueOf() - pass));
var increase_time = function() {
that.time_now += (moment().valueOf() - that.time_now);
};
var update_time = function() {
clock.html(moment(that.time_now).utc().format("YYYY-MM-DD HH:mm") + " GMT");
};
update_time();
clearInterval(clock_handle);
clock_handle = setInterval(function() {
increase_time();
update_time();
}, 500);
},
};
and in my WS open event
if(isReady()=== true){
if (clock_started === false) {
page.header.start_clock_ws();
}
}
In my WS onmessage event
if(type ==='time'){
page.header.time_counter(response);
}
Base on your suggestion, i modified my increase_time_by to
var increase_time_by = function() {
that.time_now += (moment().valueOf() - that.time_now);
};
It seems fine now. Would test further and see.
Instead of incrementing the clock by the value of the interval, just update the clock to the current time with each pass. Then it won't matter if you fire exactly 1000 ms apart or not.
You actually may want to run more frequently, such as every 500 ms, to give a smoother feel to the clock ticking.
Basically, it comes down to the precision of the timer functions, or lack thereof. Lots of questions on StackOverflow about that - such as this one.
Based on your comments, I believe you are trying to display a ticking clock of UTC time, based on a starting value coming from a web service. That would be something like this:
var time_from_ws = // ... however you want to retrieve it
var delta = moment().diff(time_from_ws); // the difference between server and client time
// define a function to update the clock
var update_time = function() {
clock.html(moment.utc().subtract(delta).format("YYYY-MM-DD HH:mm") + " GMT");
};
update_time(); // set it the first time
setInterval(update_time, 500); // get the clock ticking

Pausing a stopwatch does not stop the time

Hopefully I can make myself clear here.
I am using the following code to run my stopwatch:
function timecounter(starttime)
{
currentdate = new Date();
details = document.getElementById('details');
stopwatch = document.getElementById('stopwatch');
var timediff = currentdate.getTime() - starttime;
if(runningstate == 0)
{
timediff = timediff + stoptime
}
if(runningstate == 1)
{
stopwatch.value = formattedtime(timediff);
refresh = setTimeout('timecounter(' + starttime + ');',10);
}
else
{
window.clearTimeout(refresh);
stoptime = timediff;
}
}
function startandstop()
{
var startandstop = document.getElementById('startandstopbutton');
if(runningstate==0)
{
startandstop.value = 'Pause';
runningstate = 1;
timecounter(starttime);
}
else
{
startandstop.value = 'Start';
runningstate = 0;
lapdate = '';
}
}
But when I select the button to pause the time, the time stops, but when I press start again, it jumps to the time that it currently is as if I had not pause the time.
I have been trying to figure out what's going on with it and have come to no success.
I believe that it might have something to do with the timecounter() function but from there I am not certain.
Any help would be greatly appreciated!
Thanks,
Brandon
I think you should use .performance.now() if you want something close to accurate in terms of ms.
Thought you had an interesting problem so I came up with a solution of my own for fun. Hope it helps. :) (UPDATES BELOW THE CODE)
http://jsfiddle.net/colbycallahan/CjDz7/1/ (cleaned it up a bit for display and rounding a bit)
Works and Requires jQuery:
HTML:
<div id="console"></div>
<input type="button" id="btn" value="start time">
<input type="button" id="btn2" value="stop time">
js:
var timerRunning = false;
var startTime;
var totalTime;
$('#console').data('totalTime', 0);
function startTimer(){
totalTime = $('#console').data('totalTime');
startTime = window.performance.now();
timerRunning = true;
function timerLoop(){
window.setTimeout(function(){
if(timerRunning){
$('#console').text(window.performance.now() - startTime + totalTime);
timerLoop();
}
}, 50);
}
timerLoop();
}
$('#btn').on('click', function(){
startTimer();
});
$('#btn2').on('click', function(){
totalTime = window.performance.now() - startTime + totalTime;
$('#console').data('totalTime', totalTime);
timerRunning = false;
});
I took your code and the first thing I did was fix what can possibly cause errors in terms of syntax regarding curly braces on separate lines from if statement, missing semicolon in the if statement for when running state is 0, one semicolon incorrectly placed in timecounter() call. You tried to call a function by making it a string, but strings never call functions. starttime is not defined before you pass it as an argument to timecounter(). Your settimeout() line should be set up outside the condition statement to call it. You unnecessarily call an else if running state is not 1. lapdate is not defined other than to make it empty string. Also refresh is not defined unless running state is 1, but is only called when refresh does not equal 1. Lastly you did not include all of the code necessary to know if additional mistakes were made nor is there enough code to know if what I rewrote will fix your issue, which is why I wrote new code(it requires jquery library to be included on your page). I don't really understand the logic of your code. One more thing: you will need to retrieve the stored value of elapsed time after a user has started timer, clicked pause, and then resumed the timer. As a thanks, you should go to JSLint.com or similar and never run your code in a browser until it passes a lint test. I am only reposting your code at the bottom and don't expect it to work. I redid my timer in vanilla javascript with no jquery required. It is here:
Works and Requires no jQuery:
<!DOCTYPE html>
<html>
<head>
</head>
<body>
<div id="console"></div>
<input type="button" id="btn" value="start time" onclick="startTimer();">
<input type="button" id="btn2" value="stop time" onclick="stopTimer();">
<input type="hidden" id="storedTime" value="0">
<script>
var timerRunning = false;
var startTime;
var totalTime;
var storedTimeInp = document.getElementById('storedTime');
var console = document.getElementById('console');
function startTimer(){
totalTime = Number(storedTimeInp.value, 10);
startTime = window.performance.now();
timerRunning = true;
function timerLoop(){
window.setTimeout(function(){
if(timerRunning){
console.innerHTML = (window.performance.now() - startTime + totalTime);
timerLoop();
}
}, 50);
}
timerLoop();
}
function stopTimer(){
totalTime = window.performance.now() - startTime + totalTime;
storedTimeInp.value = totalTime;
timerRunning = false;
}
</script>
</body>
</html>
Your Code Rewritten Kinda(broken):
var runningstate = 0;
function timecounter(starttime){
currentdate = new Date();
details = document.getElementById('details');
stopwatch = document.getElementById('stopwatch');
var timediff = currentdate.getTime() - starttime;
setTimeout(
if(runningstate == 0){
timediff = timediff + stoptime;
}else{
stopwatch.value = formattedtime(timediff);
timecounter(starttime);
stoptime = timediff;
}
,10);
}
function startandstop(){
var startandstop = document.getElementById('startandstopbutton');
if(runningstate==0){
startandstop.value = 'Pause';
runningstate = 1;
starttime = new Date();
starttime = starttime.getTime();
timecounter(starttime);
}else{
startandstop.value = 'Start';
runningstate = 0;
lapdate = '';
}
}

Countdown timer for use in several places at same page

I want to make a countdown timer, that can be used on several places in the same page - so I think it should be a function in some way.
I really want it to be made with jQuery, but I cant quite make it happen with my code. I have e.g. 10 products in a page, that I need to make a countdown timer - when the timer is at 0 I need it to hide the product.
My code is:
$(document).ready(function(){
$(".product").each(function(){
$(function(){
var t1 = new Date()
var t2 = new Date()
var dif = t1.getTime() - t2.getTime()
var Seconds_from_T1_to_T2 = dif / 1000;
var Seconds_Between_Dates = Math.abs(Seconds_from_T1_to_T2);
var count = Seconds_Between_dates;
var elm = $(this).attr('id');
alert(elm);
countdown = setInterval(function(){
$(elm + " .time_left").html(count + " seconds remaining!");
if (count == 0) {
$(this).css('display','none');
}
count--;
}, 1000);
});
});
});
EDIT 1:
$(document).ready(function(){
$(".product").each(function(){
var elm = $(this).attr('id');
$(function(){
var t1 = new Date()
var t2 = new Date()
var dif = t1.getTime() - t2.getTime()
var Seconds_from_T1_to_T2 = dif / 1000;
var Seconds_Between_Dates = Math.abs(Seconds_from_T1_to_T2);
var count = Seconds_Between_dates;
alert(elm);
countdown = setInterval(function(){
$(elm + " .time_left").html(count + " seconds remaining!");
if (count == 0) {
$(this).css('display','none');
}
count--;
}, 1000);
});
});
});
Do you have any solutions to this?
I'd probably use a single interval function that checks all the products. Something like this:
$(function() {
/* set when a product should expire.
hardcoded to 5 seconds from now for demonstration
but this could be different for each product. */
$('.product').each(function() {
$(this).data('expires', (new Date()).getTime() + 5000);
});
var countdown_id = setInterval(function() {
var now = (new Date()).getTime();
$('.product').each(function() {
var expires = $(this).data('expires');
if (expires) {
var seconds_remaining = Math.round((expires-now)/1000);
if (seconds_remaining > 0) {
$('.time-left', this).text(seconds_remaining);
}
else {
$(this).hide();
}
}
});
}, 1000);
});
You could also cancel the interval function when there is nothing left to expire.
Your problem seems to be that this doesn't refer to the current DOM element (from the each), but to window - from setTimeout.
Apart from that, you have an unnecessary domReady wrapper, forgot the # on your id selector, should use cached references and never rely on the timing of setInterval, which can be quite drifting. Use this:
$(document).ready(function(){
$(".product").each(function(){
var end = new Date(/* from something */),
toUpdate = $(".time_left", this);
prod = $(this);
countDown();
function countdown() {
var cur = new Date(),
left = end - cur;
if (left <= 0) {
prod.remove(); // or .hide() or whatever
return;
}
var sec = Math.ceil(left / 1000);
toUpdate.text(sec + " seconds remaining!"); // don't use .html()
setTimeout(countdown, left % 1000);
}
});
});

Debugging JavaScript Timing Events

I'm having a problem with this JavaScript script. I've tried a number of things to get it to work. The alerts in there at current are there for debugging purposes, and seem to be failing to occur.
Help please?
function checkTime(this_time){
var the_string = "checkTime("+this_time+")";
var now = ((new Date()).getTime());
if(parseInt(now) >= parseInt(this_time)){
document.write("TIMEUP!");
}
alert(now);
alert(this_time);
var t = setTimeout(the_string,300);
}
var the_time = (((new Date()).getTime())+19000);
var the_string = "checkTime("+the_time+")";
var t = setTimeout(the_string,300);
Thanks,
Will.
Seems like you're looking for a countdown?
See this fiddle. The code is simplified to:
var bench = 19000 + new Date().getTime(),
timer = setInterval(
function(){
checkTime(bench);
}
, 1000
);
function checkTime(this_time){
var check = new Date - this_time;
if(check>=0){
alert('time\'s up!');
clearInterval(timer);
}
}
You should use setTimeout with closures instead of strings.
var now = new Date().getTime();
setTimeout(function(){
//your Javascript code here
//"now" can be used here as a closure
}, 300);
Here is a safer and self-contained version. A document.write after load will clear the page completely
http://jsfiddle.net/mplungjan/Zt5k7/
window.onload=function() {
var timer = function (endTime) {
var end = new Date(endTime);
var tId;
this.checkTime=function(){
var now = new Date();
document.getElementById("msg").innerHTML=now.toLocaleString();
if (now.getTime()>=end.getTime()) {
document.getElementById("msg").innerHTML="TIME's UP!";
clearInterval(tId);
}
}
tId = setInterval(this.checkTime,300);
}(new Date().getTime()+5000);
}
or for a proper countdown http://jsfiddle.net/mplungjan/Zt5k7/1/
window.onload=function() {
var timer = function (endTime) {
var end = new Date(endTime);
var tId;
this.checkTime=function(){
var now = new Date();
document.getElementById("msg").innerHTML=now.toLocaleString();
var diff = end.getTime()-now.getTime()
if (diff >= 1) document.getElementById("msg").innerHTML=parseInt(diff/1000)+1;
else {
document.getElementById("msg").innerHTML="TIME's UP!";
clearInterval(tId);
}
}
tId = setInterval(this.checkTime,300);
}(new Date().getTime()+9000);
}
I suppose the code could be made more simple to work.
function checkTime(this_time){
var now = ((new Date()).getTime());
if((now - this_time) >= 0){
document.write("TIMEUP!");
window.clearInterval(timer);
}
}
var t_t = (((new Date()).getTime())+19000);
var timer = window.setInterval(function(){
checkTime(t_t); }
, 300);
Cheers!

Categories

Resources