I'm using count down timer by this code. If the page refresh or reload the count should not be reset for that I'm using this from localstorage. If there any alternate solution for this means Please suggest me.
var hms = $(".div__time .total_time").text();
var a = hms.split(':');
var hrs_min_sec = (+a[0]) * 60 * 60 + (+a[1]) * 60 + (+a[2]);
var time_hrs_min_sec = hrs_min_sec;
if (localStorage.getItem("counter")) {
if (localStorage.getItem("counter") <= 0) {
var value = time_hrs_min_sec;
} else {
var value = localStorage.getItem("counter");
}
} else {
var value = time_hrs_min_sec;
}
document.getElementById('overall_time').innerHTML = value;
var counter = function() {
if (value <= 0) {
localStorage.setItem("counter", time_hrs_min_sec);
} else {
value = parseInt(value) - 1;
console.log(value);
localStorage.setItem("counter", value);
}
document.getElementById('overall_time').innerHTML = value;
if (value == 0) {
// var redirect_url = "<?php echo site_url('home'); ?>";
// window.location.href = redirect_url;
}
var hours = Math.floor(value / 3600);
var minutes = Math.floor(value % 3600 / 60);
var seconds = Math.floor(value % 3600 % 60);
var red_time = hours + ' : ' + minutes + ' : ' + seconds;
document.getElementById('overall_times').innerHTML = red_time;
};
var interval = setInterval(function() {
counter();
}, 1000);
#overall_time {
display: none;
}
.div__time,
.total_time,
#overall_times {
display: inline-block;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div class="div__time">
<div id="overall_time"></div>
<div id="overall_times"></div> /
<div class="total_time">
00:00:10
</div>
</div>
<button onclick="start_over_all_time(this);" id="over_all_time">Over All Time</button>
This one working fine.
When I click a button I need to reset the countdown value to 0. For example if countdown time counting from 10 to 0 if click a button at count 5. then the count has to be reset to 0. This point only not working for me.
I'm using this code for reset the localstorage value
function start_over_all_time(button) {
var inputElemnets = '0';
localStorage.setItem("value", inputElemnets);
console.log(value);
}
Fiddle Link
Thanks in Advance.
Okay... To objective here is to make the countdown "set to zero" button working.
Since SO snippet do not allow localStorage, the working scrip is on CodePen.
The main issue was not having declared the value at global scope.
See explanations within the code.
// I removed the 3 lines below because that was the only use of jQuery afer all...
// And because the math is weird to read (and incorrect).
//var hms = $(".div__time .total_time").text();
//var a = hms.split(':');
//var hrs_min_sec = (+a[0]) * 60 * 60 + (+a[1]) * 60 + (+a[2]);
// Replaced by this:
var hms = document.querySelector(".total_time").innerHTML;
var hms_arr = hms.split(":");
var time_hrs_min_sec = (hms_arr[0]*3600) + (hms_arr[1]*60) + hms_arr[2];
// Declare the "value" used in almost all functions at the global scope.
var value;
if (localStorage.getItem("counter")) {
if (localStorage.getItem("counter") <= 0) {
value = time_hrs_min_sec; // Removed the var
} else {
value = localStorage.getItem("counter"); // Removed the var
}
} else {
value = time_hrs_min_sec; // Removed the var
}
document.getElementById('overall_time').innerHTML = value;
var counter = function() {
if (value <= 0) {
localStorage.setItem("counter", time_hrs_min_sec);
} else {
value = parseInt(value) - 1;
console.log(value);
localStorage.setItem("counter", value);
}
document.getElementById('overall_time').innerHTML = value;
if (value == 0) {
// var redirect_url = "<?php echo site_url('home'); ?>";
// window.location.href = redirect_url;
}
var hours = Math.floor(value / 3600);
var minutes = Math.floor(value % 3600 / 60);
var seconds = Math.floor(value % 3600 % 60);
var red_time = hours + ' : ' + minutes + ' : ' + seconds;
document.getElementById('overall_times').innerHTML = red_time;
};
var interval = setInterval(function() {
counter();
}, 1000);
// Use value here... Instead of inputElemnets
function start_over_all_time(button) {
value = 0;
localStorage.setItem("counter", value);
console.log(value);
// Be cool with the browser and stop the interval.
setTimeout(function(){
clearInterval(interval);
},1000);
}
Now the set to zero button works... because you use the value variable everywhere. So as soon as you set it to zero, in start_over_all_time(), the next iteration of the interval will do the rest.
There is plenty other things to fix... But that was your question.
When it comes to caching user data, you have 2 options:
HTML5 storage (no backend required) => LocalStorage or SessionStorage
Cookies (backend required)
LocalStorage or SessionStorage
Instead of LocalStorage you could use SessionStorage. The difference is, that it lives only as long as the browser session is open, i.e. closing the browser will end the session and delete the storage.
It's up to you, which of the both you want to use.
For more, check out this SO question.
Cookies
Cookies are primarily for reading server-side, local storage can only be read by the client-side.
If I understand you correctly, you only want to save some UI state rather than have the server/backend remember this state.
In comparison to html5 storage, cookies are:
smaller
have an expiration date
are harder to implement (as it requires a backend)
For more, check out this SO question.
Edit: Cookies can actually be set and read by js alone, thanks for correcting me #jon-p
Related
I have the following code and cannot get the chat timestamp to update without refresh. I am new to javascript.
function timeSince(date) {
var seconds = Math.floor((new Date() - date) / 1000);
var interval = seconds / 31536000;
if (interval > 1) {
return Math.floor(interval) + " years";
}
interval = seconds / 2592000;
if (interval > 1) {
return Math.floor(interval) + " months";
}
interval = seconds / 86400;
if (interval > 1) {
return Math.floor(interval) + " days";
}
interval = seconds / 3600;
if (interval > 1) {
return Math.floor(interval) + " hours";
}
interval = seconds / 60;
if (interval > 1) {
return Math.floor(interval) + " minutes";
}
return Math.floor(seconds) + " seconds";
}
setInterval(timeSince, 1000);
var aDay = 24*60*60*1000;
console.log(timeSince(new Date(Date.now()-aDay)));
console.log(timeSince(new Date(Date.now()-aDay*2)));
const dates = new Date(message.timestamp)
if (message.user === currentUser) position = 'right';
const messageItem = `
<div class="message ${position}">
<span class="small">${timeSince(dates)}</span><br>
I tried: setInterval(timeSince, 1000); and setInterval(timeSince(), 1000); and setInterval(timeSince(date, 1000); and tried each in different place within the function, can't get to work.
timeSince just returns your formatted string with the duration. Setting an interval on this function will do practically nothing. You have to use the return value.
setInterval(function(){
var time = timeSince(message.timestamp);
//You can use a better selector here,
//but without more information, this is the best I can do.
document.getElementsByClassName("small")[0].innerHTML = time;
}, 1000);
found a half solution. I had to insert the setInterval under the function that calls the function under which sits the timesince function. Now the whole thing updates after the interval i set and not just the time, but setting an update interval of 1 minute makes it fine with me.
Apparently since I have several functions under one, the setInterval doesn't work, or didn't work in my case.
draw message is the function under which the timeSince function resides
Maybe coz i didn't provide this info here before i didn't get the right help
Solution:
this:
function getConversation(recipient) {
setInterval(function(){
$.getJSON(`/api/v1/message/?target=${recipient}`, function (data) {
messageList.children('.message').remove();
for (let i = data['results'].length - 1; i >= 0; i--) {
drawMessage(data['results'][i]);
}
messageList.animate({scrollTop: messageList.prop('scrollHeight')});
});
}, 60000);}
or this:
function getConversation(recipient) {
$.getJSON(`/api/v1/message/?target=${recipient}`, function (data) {
messageList.children('.message').remove();
for (let i = data['results'].length - 1; i >= 0; i--) {
drawMessage(data['results'][i]);
}
**setInterval(getConversation(recipient), 1000);**
messageList.animate({scrollTop: messageList.prop('scrollHeight')});
});
}
Thank you David for your help
I implemented a timer count on my examination page. It is just like the edmodo website. But when you're taking an exam in edmodo, even if you refresh it, the timer is still counting. On my site, if you refresh the page, the timer refresh too. What I want is just like the edmodo which still counting even you refresh the page. Please see my code for your reference.
Note:
I'm using Laravel5.1/jQuery
$(document).ready(function() {
// Quiz timer (Start of Quiz)
var quiz_timer = $('.quiz-timer').html();
var exact_time = parseInt($('.timer-value').html() - 1);
var hrs_to_spend = parseInt(exact_time / 60);
var mins_to_spend = parseInt(exact_time % 60);
var secs_to_spend = 60;
var timeIsUp = false;
var secs = 0,
mins = 0,
hrs = 0;
var secs_zero, mins_zero, hrs_zero, h_spend_zero, m_spend_zero, s_spend_zero;
var setters = setInterval(function() {
if ($('.quiz-timer').html() != '00:00:01') {
if (secs_to_spend > 0) {
secs_to_spend--;
}
if (secs_to_spend <= 0) {
mins_to_spend--;
secs_to_spend = 59;
}
if (mins_to_spend < 0) {
hrs_to_spend--;
mins_to_spend = 59;
}
} else {
$('.quiz-timer').html('00:00:00')
clearInterval(setters);
$('.answer-quiz > .panel-info').attr('class', 'panel panel-danger');
swal({
title: "Oops!",
text: "Time is up.",
type: "warning"
});
timeIsUp = true;
setTimeout(function() {
$('#submitAttempt').click();
}, 2000);
return false;
}
h_spend_zero = (hrs_to_spend < 10) ? '0' : '';
m_spend_zero = (mins_to_spend < 10) ? '0' : '';
s_spend_zero = (secs_to_spend < 10) ? '0' : '';
$('.quiz-timer').html(h_spend_zero + hrs_to_spend + ':' + m_spend_zero + mins_to_spend + ':' + s_spend_zero + secs_to_spend);
if (!timeIsUp) {
secs++;
if (secs == 60) {
mins++;
secs = 0;
}
if (mins == 60) {
hrs++;
mins = 0;
}
hrs_zero = (hrs < 10) ? '0' : '';
mins_zero = (mins < 10) ? '0' : '';
secs_zero = (secs < 10) ? '0' : '';
$('#timeTaken').val(hrs_zero + hrs + ':' + mins_zero + mins + ':' + secs_zero + secs);
}
}, 1000);
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
Original Value: <span class="timer-value">110</span><br><br>
Timer: <span class="quiz-timer"></span><br>
Time Spent: <input type="text" name="time_taken" id="timeTaken" value="">
Set time expiration deadline as a date-time. Count remaining time, not spent time.
For example if date-time now is "2017-08-22 08:00:01" (the starting time of the exam), and you want the expiration after 1 hour, set the date-time deadline to "2017-08-22 09:00:01" (this should be returned from the server). Then let the javascript counter recalculate the difference between the time now and the deadline with refresh rate (interval) every second.
use local storage
1) save the last time in localstorage
like
window.onbeforeunload= function(){
localStorage.setItem("lastTime", timevalue);
}
2) upon reload if time exists in localstorage like
savedTime = localStorage.getItem("lastTime");
mytimer.continueFrom(savedTime)
pick it up from that point and continue the timer
have a look here about localstorage
Local Storage
You can't achieve that with Javascript, javascript code has a session life time, if you close the tab it terminates all the resources that the tab used, including javascript.
You can try to overcome that via saving the counter + current time in local storage, and whenever you start your JS code, check if there are those values in the local storage, and init the counter value with them.
let counter = prevSavedCounter + (new Date()).getTime() - savedTime;
i want this my javascript code to to be able to be reading 3 hours countdown and also redirect to a new page after the countdown is complete
<script type="text/javascript">
// properties
var count = 0;
var counter = null;
window.onload = function() {
initCounter();
};
function initCounter() {
// get count from localStorage, or set to initial value of 1000
count = getLocalStorage('count') || 1000;
counter = setInterval(timer, 1000); //1000 will run it every 1 second
}
function setLocalStorage(key, val) {
if (window.localStorage) {
window.localStorage.setItem(key, val);
}
return val;
}
function getLocalStorage(key) {
return window.localStorage ? window.localStorage.getItem(key) : '';
}
function timer() {
count = setLocalStorage('count', count - 1);
if (count == -1) {
clearInterval(counter);
return;
}
var seconds = count % 60;
var minutes = Math.floor(count / 60);
var hours = Math.floor(minutes / 60);
minutes %= 60;
hours %= 60;
document.getElementById("timer").innerHTML = hours + "hours " + minutes + "minutes and " + seconds + " seconds left to complete this transaction"; // watch for spelling
}
</script>
<div id="timer"></div>
please help me make it better by making it been able to countdown to three hour and also redirect to another page after the countdown is complete
You didn't properly set total time. You set it to 16 minutes instead of 3 hours. Here is the working code (try it on JSFiddle):
var time = 60 * 60 * 3;
var div = document.getElementById("timer");
var t = Date.now();
var loop = function(){
var dt = (Date.now() - t) * 1e-3;
if(dt > time){
doWhateverHere();
}else{
dt = time - dt;
div.innerHTML = `Hours: ${dt / 3600 | 0}, Minutes: ${dt / 60 % 60 | 0}, Seconds: ${dt % 60 | 0}`;
}
requestAnimationFrame(loop);
};
loop();
Also, do not use setInterval and setTimeout for precise timing. These functions are volatile. Use Date.now() instead.
My 14 yr old son is working on a Science Project looking at reaction time and age. He is setting up a little web app to test people - When a page is loaded a timer starts and there is a delay in a STOP button appearing (4 secs for this example). When they click the stop button, the timer stops.
He's done a great job of coding all of that so far. He is using a piece of JavaScript that he found and has modified it to his needs.
His issue - how to pass the stopped time into a variable and then pass that to another page. He is able to successfully do it if the variable is static ie "Hello."
What is wrong with the function stop(); in this example? He currently gets a [object HTMLSpanElement]
var clsStopwatch = function() {
// Private vars
var startAt = 0; // Time of last start / resume. (0 if not running)
var lapTime = 0; // Time on the clock when last stopped in milliseconds
var now = function() {
return (new Date()).getTime();
};
// Public methods
// Start or resume
this.start = function() {
startAt = startAt ? startAt : now();
};
// Stop or pause
this.stop = function() {
// If running, update elapsed time otherwise keep it
lapTime = startAt ? lapTime + now() - startAt : lapTime;
startAt = 0; // Paused
};
// Reset
this.reset = function() {
lapTime = startAt = 0;
};
// Duration
this.time = function() {
return lapTime + (startAt ? now() - startAt : 0);
};
};
var x = new clsStopwatch();
var $time;
var clocktimer;
function pad(num, size) {
var s = "0000" + num;
return s.substr(s.length - size);
}
function formatTime(time) {
var h = m = s = ms = 0;
var newTime = '';
h = Math.floor( time / (60 * 60 * 1000) );
time = time % (60 * 60 * 1000);
m = Math.floor( time / (60 * 1000) );
time = time % (60 * 1000);
s = Math.floor( time / 1000 );
ms = time % 1000;
newTime = pad(h, 2) + ':' + pad(m, 2) + ':' + pad(s, 2) + ':' + pad(ms, 3);
return newTime;
}
function update() {
$time.innerHTML = formatTime(x.time());
}
function start() {
$time = document.getElementById('time');
update();
clocktimer = setInterval("update()", 1);
x.start();
$(document).ready(function() { $('#mybutton').delay(4000).fadeIn(0);});
}
function stop() {
x.stop();
//var varTime = "Hello";
var varTime = document.getElementById('time');
window.location.href = "somephpfile.php?etime=" + varTime;
}
The var varTime = document.getElementById('time') is assigning the element to the varible, which is fine and not a bad option however I believe your son only needs the HTML text of that element.
There are two options. The first option keeps the time element in the function for possible expansion later.
function stop() {
x.stop();
var varTime = document.getElementById('time');
if (varTime) {
window.location.href = "somephpfile.php?etime=" + varTime.innerHTML;
}
}
Or just extract the required text and send it - even if it is empty.
function stop() {
x.stop();
if (document.getElementById('time')) {
window.location.href = "somephpfile.php?etime=" + document.getElementById('time').innerHTML;
}
}
You need to read the innerHTML of the element instead if just reading element itself. This can be accomplished by :
function stop() {
x.stop();
//var varTime = "Hello";
var varTime = document.getElementById('time').innerHTML;
window.location.href = "somephpfile.php?etime=" +
}
I have a page where I want to have "age counters" for bids put in by users. The number of users will vary from situation to situation, so that needs to be taken into consideration. I wrote this:
function timer(i) {
// this selects a 'hh:mm:ss' timestamp
if ($("#time_0" + i).text() !== "") {
var now = new Date();
var date = now.toDateString();
var tStamp = new Date(date + "," + $("#time_0" + i).text());
var diff = now - tStamp;
var mins = Math.floor(diff / (1000 * 60));
var secs = Math.floor((diff / 1000) % 60);
if (mins < 10) {
mins = "0" + mins;
}
if (secs < 10) {
secs = "0" + secs;
} else if (secs == 60) {
secs = "00";
}
$("#user" + i + "-t").text(mins + ':' + secs);
}
}
$(document).ready(function() {
//
var ids = [];
$("td[id^='time_0']").each(function() {
var i = ($(this).attr("id")).slice(-1);
ids.push(i);
});
for (i in ids) { // in my example ids = [1,2,3]
setInterval(function() {timer(i);}, 1000);
}
});
The timer itself functions just as I want it to, but only for user #2 (the middle one). I thought that if I encountered this problem, it would be either the first or last user in the list that had a working timer, but I'm getting blank cells for users #1 and #3.
Does anyone have any ideas as to how I can fix this? Thank you for your time.
==Edit==
I made a bare-bones jsfiddle
In your version loop never went past first reference, which was timer(0), because you called your function with timer(i), which was calling the first key in the array ids. When you have setInterval in a loop it will keep looping the first setInterval until that is terminated. By putting that i in an anonymous function, each setInterval gets fired.
$(document).ready(function () {
var ids = [];
$("td[id^='time_0']").each(function () {
var i = $(this).attr("id").slice(-1);
ids.push(i);
});
for (i in ids) {
(function(i) { // i needs to be stored into a anonymous function otherwise it gets overwritten
setInterval(function() {
timer(ids[i]); // calling just timer(i) would use array keys, not the actual values - ids[i] means: "give me the value of the key of i"
}, 1000)
})(i);
}
});
Made changes to your Fiddle