here's what I mean:
I have written up a simple timer that counts down from 5 minutes. At the end of 5 minutes, I'd like to display a button for my user to press. You can see my code at the end of this post.
I do not want the user to be able to press see the button before the timer runs out. I don't want the user to be able to go into the JS console and call "document.getElementById("button").style.display = 'block';" and have access to the button.
What are some ways I can do this, preferably entirely on the client side? Is there a way to do this entirely on the client side?
My backend is Ruby on Rails - if there's an easy solution using RoR, I'd be curious about that too. But frankly, I'd love to know if there's a fully client side way of doing this!
<html>
<script>
function startTimer(duration, display) {
var start = Date.now(),
diff,
minutes,
seconds;
function timer(timerIntervalId) {
diff = duration - (((Date.now() - start) / 1000) | 0);
minutes = (diff / 60) | 0;
seconds = (diff % 60) | 0;
minutes = minutes < 10 ? "0" + minutes : minutes;
seconds = seconds < 10 ? "0" + seconds : seconds;
display.textContent = minutes + ":" + seconds;
if (minutes == "00" && seconds == "00" && timerIntervalId != undefined) {
clearInterval(timerIntervalId);
document.getElementById("button").style.display = 'block';
}
if (diff <= 0) {
start = Date.now() + 1000;
}
};
timer();
var timerIntervalId = setInterval(function() { timer(timerIntervalId) }, 1000);
}
window.onload = function () {
var timerLength = 60 * .15,
display = document.querySelector('#time');
startTimer(timerLength, display);
};
</script>
<body>
<div>Registration closes in <span id="time"></span> minutes!</div>
<div id = "button" style = "display: none;">BUTTON</div>
</body>
</html>
I hate to say it bud, but there is no such thing as secure in javascript. A user with a little knowledge will be able to do anything they want to your code. But to attempt to give a suggestions
if (minutes == "00" && seconds == "00" && timerIntervalId != undefined) {
clearInterval(timerIntervalId);
///document.getElementById("button").style.display = 'block';
$("<div>").attr('id', 'button').appendTo($("#placeholder")).text("button")
}
<body>
<div>Registration closes in <span id="time"></span> minutes!</div>
<div id="placeholder">
</div>
</body>
</html>
this way the button doesnt exist until you create it at the end of the timer
https://jsfiddle.net/u3bae0uj/
There is no fully client side solution. Because if yo implement this fully using client side, user can at some way change the timer (as you said, show button).
To be sure that 5 minutes will pass you will have to communicate with server, but can implement this using ajax.
At timer start you can call some action at server and start timer on server side, using sessions variable, when 5 minutes pass you execute ajax call on other action an check if 5 minutes have pass (this way you get 5 minutes, and user can not change it on client).
If 5 minutes have passed, you return html to user, inside html you return the button you want to show, so user can not inspect html, and set it visible, because server returns button after 5 minutes, and then user can click on it.
Related
<html>
<head>Harshal</head>
<script>
var limit="5:0"
var doctitle = document.title
var parselimit=limit.split(":")
parselimit=parselimit[0]*60+parselimit[1]*1
function beginrefresh(){
if (parselimit==1)
window.location.reload()
else{
parselimit-=1
curmin=Math.floor(parselimit/60)
cursec=parselimit%60
if (curmin!=0)
curtime=curmin+" minutes and "+cursec+" seconds left until page refresh!"
else
curtime=cursec+" seconds left until page refresh!"
document.title = doctitle + ' (' + curtime +')'
setTimeout("beginrefresh()",1000)
}
}
if (window.addEventListener)
window.addEventListener("load", beginrefresh, false)
else if (window.attachEvent)
window.attachEvent("load", beginrefresh)
</script>
</html>
This is my demo code. I'm refreshing the page every 5 minutes when someone clicks on the link and the tab title counts down the 5 fives. However, I cannot figure out how I can start the refresh at 8:01 a.m and then again at 8:06 am and then again at 8:11 a.m. and just keeps going and doesn't depend on when someone clicks on it.
Any help?
To achieve expected result, use SetInterval
SetInterval for every minute (1000*60)
GetTime in Hours and Minutes separately
Start after 8am or anytime after 8am
Check every 5 mins to refresh
refresh window
setInterval(function(){
var currTimeHr = new Date().getHours();
var currTimeMin = new Date().getMinutes();
if(currTimeHr >= 8){ //start at 8 or at any point after 8am
if(currTimeMin%5 === 0){ // check every 5 mins
window.location.reload(true); //refresh page
}
}
}, 1000*60)
code sample - https://codepen.io/nagasai/pen/MXVWxb?editors=1010
use set interval.
setInterval(function() {
window.location.reload();
}, 300000);
setinterval is in ms (5mins = 300k ms)
The new page (after refresh) has no awareness of the previous page's state. So you need a way to pass that state forward, through a query parameter or something.
My approach would be to just reload the page when they clicked the link, and have the new page set itself to refresh after 5 minutes (keeping the same url so we're loading the page with the refresh code).
if(window.location.search.includes('refresh')){
setTimeout(function(){//we're in "refresh mode" so just wait 5 minutes and do it again
location.href = location.href;
}, 1000 * 60 * 5);
}
refresh every five minutes
the example doesn't seem to work because the navigation. but it should work in theory
To start at specified time use the following "wait" function
var startHour = 8;
var startMinute = 5;
function wait() {
var startTime = currentTime = new Date();
startTime.setHours(startHour);
startTime.setMinutes(startMinute);
if (startTime < currentTime) {
setTimeout(wait, 1000);
} else {
// run refresh function here
}
}
I am doing an online examination page. In this page I have a countdown timer that counts down by a value from the database. It's working fine but when I refresh the page it resets. I have to stop the timer from resetting.
Here is my JavaScript timer code:
<script type="text/javascript">
function CountDown(duration, display) {
if (!isNaN(duration)) {
var timer = duration, minutes, seconds;
var interVal = setInterval(function () {
minutes = parseInt(timer / 60, 10);
seconds = parseInt(timer % 60, 10);
minutes = minutes < 10 ? "0" + minutes : minutes;
seconds = seconds < 10 ? "0" + seconds : seconds;
$(display).html("<b>" +"Time Remaining: "+ minutes + "m : " + seconds + "s" + "</b>");
if (--timer < 0) {
timer = duration;
SubmitFunction();
$('#display').empty();
clearInterval(interVal)
}
},1000);
}
}
function SubmitFunction(){
$('#result').click();
}
CountDown(<?php echo $t*30; ?>,$('#display')); //$t comes from database
function disable_f5(e) {
if ((e.which || e.keyCode) == 116) {
e.preventDefault();
}
}
$(document).ready(function(){
$(document).bind("keydown", disable_f5);
});
</script>
I just saw your question and am going to take a crack at it. One thing that I recommend is trying to commit the values to local storage. You could add an event listener, have it specify to listen for a reload, and on that reload commit the integer value to local storage in JSON format. Just an idea.
If you are using a db already, what about adding a table or an extra field to an existing table that registers the datetime that the user commenced the examination and then on each page load - you can get the commencement time from the db, do some funky calculations and then display the remaining time.
That way you are not relying on the calculation in browser keeping track (although I would probably try session storage for it as already suggested), but a constant start time that you can confidently calculate from.
try this as an approach - note only skeleton of code listed to demonstrate approach. I would personally set the datetime in the db though.
//at commencement of exam
//js var commencementTime = (//calculation to get current time);
localStorage.setItem('commencementTime ',commencementTime );
//on page reload
var commencementTime= localStorage.getItem('commencementTime ');
if(commencementTime){
//code for calculating countdown}
I need a countdown that will refresh a page, and I think I've finally got it, except for one thing. I'd like the countdown to be in minutes and seconds, not just seconds (the countdown is for one hour). A simple MM:SS format would be fine, but also writing out minutes and seconds would work. Can anybody help?
<SCRIPT LANGUAGE="JavaScript">
<!--
var counterobj = document.all ? counter : document.getElementById("counter");
var countdownfrom = 3600; //countdown period in seconds
var currentsecond = counterobj.innerHTML = countdownfrom+1;
function countdown()
{
if (currentsecond!=1)
{
currentsecond-=1;
counterobj.innerHTML = currentsecond;
}
else
{
self.location.reload();
return;
}
setTimeout("countdown()",1000)
}
countdown()
//-->
</script>
Calculate minutes using a floor doing like
minute = Math.floor(currentsecond/60);
Then just output as normal.
edit -- fixed! Hopefully! (accidentally said to use mod -- you need to use Floor, I believe)
I've got a ColdFusion application that I am developing that requires a timer that can start, pause, and clear. My problem is that although it works perfectly fine in IE9, Firefox, Opera, Chrome, and Safari, it will not work in IE8 (which is a huge chunk of my userbase). The issue is that when I click and try to stop the timer, instead of the timer stopping, it speeds up. It only does it in IE8 (the other browsers work fine).
-- CLOCK CODE --
function check_timer() {
if($('#timer').hasClass('start')) {
$('#timer').val("Stop Timer");
timer = setInterval ( "increaseCounter()", 1000 );
$('#timer').removeClass('start')
}
else {
if(typeof timer != "undefined") {
clearInterval(timer);
}
$('#timer').val("Start Timer");
$('#timer').addClass('start')
}
}
function increaseCounter() {
var secVal;
var minVal;
secVal = parseInt($('#counterSec').html(),10)
minVal = parseInt($('#counterMin').html(),10)
if(secVal != 59) {
secVal = secVal + 1;
if(secVal < 10) {
secVal = secVal.toString();
secVal = "0" + secVal;
}
$('#counterSec').html(secVal);
}
else {
if(minVal != 59){
minVal = minVal + 1;
if(minVal < 10) {
minVal = minVal.toString();
minVal = "0" + minVal;
}
$('#counterMin').html(minVal);
}
else {
$('#counterHour').html((parseInt($('#counterHour').html(),10)+1));
$('#counterMin').html("00");
}
$('#counterSec').html("00");
}
}
-- DIV CONTAINING CLOCK --
<div class="supportClock" style="width:150px; border-radius:20px;" align="center">
<span id="addZeroHour"></span>
<span id="counterHour">00</span>
:<span id="addZeroMin"></span>
<span id="counterMin">00</span>
:<span id="addZeroSec"></span>
<span id="counterSec">00</span>
</div>
-- BUTTON TO ACTIVATE CLOCK --
<input type="button" id="timer" class="start" value="Start Timer" onclick="check_timer()">
add this to the top of your script(outside the functions):
var timer;
Otherwise you will never run into this branch:
if(typeof timer != "undefined")
The reason: there is an element with the ID "timer", you may access it by using timer without the suggested modification and timer will never be of type "undefined"
Or simply use another name for the timeout-variable.
Have a look here: http://jsfiddle.net/qEATW/3/
Even if you set an interval to be, for example, one second, it won't necessarily be one second between calls.
For timeouts and intervals, always pass in the function, never a string: setInterval(increaseCounter, 1000)
There's no reason to parse values from the DOM. It's incredibly inefficient to do so. If you instead use Date differences, you can simply store one variable (start time), and get hours/mins/seconds since that time. You can update the view however often you like and it will always be accurate.
I personally prefer "recursive" timeouts as opposed to intervals. With intervals, you'll always need to take that extra step to clear the interval when you want it to stop. You can stop a timeout loop in several different ways, and it tends to be easier to understand what's going on. Timeouts also allow us the flexibility of changing the time between calls (not that that is relevant here).
It is considered a bad practice to bind event handlers inline (on the HTML element). If you are already using jQuery, there's really no excuse for this as jQuery makes the process so very simple.
I got rid of the "addZero" spans that you had. I'm not sure what you were doing with them, but they weren't necessary and only served to clutter the markup.
HTML:
<div class="supportClock" style="width:150px; border-radius:20px;" align="center">
<span id="counterHour">00</span>
: <span id="counterMin">00</span>
: <span id="counterSec">00</span>
</div>
<input type="button" id="timer" class="start" value="Start Timer">
JS:
(function(){
var clock = $(".supportClock"),
hr = $("#counterHour"),
min = $("#counterMin"),
sec = $("#counterSec"),
running = false,
startTime,
timeout;
function updateClock(){
var time = (new Date()) - startTime,
hrs = Math.floor(time / 1000 / 60 / 60),
mins = Math.floor(time / 1000 / 60 - hrs * 60),
secs = Math.floor(time / 1000 - mins * 60 - hrs * 60 * 60);
hr.text(hrs > 9 ? hrs : '0' + hrs);
min.text(mins > 9 ? mins: '0' + mins);
sec.text(secs > 9 ? secs : '0' + secs);
timeout = setTimeout(updateClock, 1000/2);
}
$("#timer").click(function(){
if (!running){
running = true;
this.value = "Stop Timer";
startTime = new Date();
updateClock();
}
else{
running = false;
this.value = "Start Timer";
clearTimeout(timeout);
}
});
})();
I have my code of timer that only alert when minutes and seconds are 0:
status = false;
hour_to_start = some_value; // THIS VALUE IS PUT FOR OTHER PERSON
min = 15; //THIS VALUE IS PUT FOR ANOTHER PERSON
seg = 60;
function timecamisa(){
if (seg > 0){
seg--;
}else{
if(seg==0){
min--;
seg=60;
}
}
if(min == 0 && seg==0){
// END - STOP ALL
min= 0;
seg = 0;
status = true;
}
var timer = min + ' minutos ' + seg + ' segundos';
document.getElementById("times-get").innerHTML = timer;
if(status != true){
setTimeout("timecamisa()",1000)//This reload this function (timecamisa())
}else{
alert("END!");
}
In my HTML i have a <span id="times-get"> where print the timer.
BUT, when i press F5 my timer return to the beginning and does not continue where you left off... So, How to do this? Anyone have a example?
My target is that my timer work with my variable 'hour_to_start' and 'min' where.. This timer displays the countdown from my variable 'hour_to_start' in 'x' 'min' (my other variable). And when the variable MIN is 0(ie, complete the mins).. Alert anything.
UPDATE!
OK, i do it with Jquery Plugin countdown Timer.. Is very useful for more than 1 timers.
Now, mi problem is.. when i change the time of my computer, this timer change too.
How to avoid changing my timer when you change the time, date and / or time of my machine?
You will need to get the time from either your server or from some remote server (e.g. via a javascript from someone else's server). If you get the time using javascript it will always depend on the clock of the user's machine.