Timer JavaScript not running in Chrome & Mozilla when window minimized - javascript

Hi I am using a Java Script timer, it works well in IE but in Chrome when the window is minimized it becomes too slow, in Mozilla it stops it timer. Can anyone suggest anything ? My code is as follows :-
<html>
<head>
<script>
var millisec = 0;
var seconds = 0;
var timer;
function display(){
if (millisec>=9){
millisec=0
seconds+=1
}
else
millisec+=1
document.d.d2.value = seconds + "." + millisec;
timer = setTimeout("display()",100);
}
function starttimer() {
if (timer > 0) {
return;
}
display();
}
function stoptimer() {
clearTimeout(timer);
timer = 0;
}
function startstoptimer() {
if (timer > 0) {
clearTimeout(timer);
timer = 0;
} else {
display();
}
}
function resettimer() {
stoptimer();
millisec = 0;
seconds = 0;
}
</script>
</head>
<body>
<h5>Millisecond Javascript Timer</h5>
<form name="d">
<input type="text" size="8" name="d2">
<input type="button" value="Start/Stop" onclick="startstoptimer()">
<input type="reset" onclick="resettimer()">
</form>
</body></html>

You can not use setTimeout to make a reliable time keeping script.
John Resig explains how JavaScript timers work: http://ejohn.org/blog/how-javascript-timers-work/
The short version is that there is always have a small delay. The millisecond parameter you pass to setTimeout is a "best effort".
If you want to show a live timer consider polling the time really often. If the event loop slows down, there is no effect on your ability to track time, you just get less updates.
http://jsfiddle.net/64pcr7pw/
<script type="text/javascript">
var timer, time = 0, start_time = 0;
function startstoptimer() {
if (timer) {
time += new Date().getTime() - start_time;
start_time = 0;
clearInterval(timer);
timer = null;
} else {
start_time = new Date().getTime();
timer = setInterval(function () {
document.d.d2.value = time + new Date().getTime() - start_time;
}, 10);
}
}
function resettimer() {
time = 0;
start_time = new Date().getTime();
document.d.d2.value = "0";
}
</script>
<form name="d">
<input type="text" size="8" name="d2"/>
<input type="button" value="Start/Stop" onclick="startstoptimer()"/>
<input type="reset" onclick="resettimer()" />
</form>

Related

Enqueue function to execute after currently running function is done executing (setTimeout)

I have a basic timer where a user puts in a number, then it counts down until it hits 0.
I want the user to put another number while the timer for the prev is still going on. When the timer for the prev number hits 0, a new timer for the recently entered number will begin. My code somehow has both timers running concurrently despite my uses of setInterval and setTimeout.
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<meta http-equiv="X-UA-Compatible" content="IE=edge" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>Document</title>
</head>
<script>
var isRunning = false;
var qNums = [];
var wrapFunction = function (fn, context, params) {
return function () {
fn.apply(context, params);
};
};
function q() {
var sec = document.getElementById("data").value;
if (!Number.isInteger(parseInt(sec))) {
document.getElementById("timer").innerHTML = "Not a number!";
return;
} else if (parseInt(sec) < 0) {
document.getElementById("timer").innerHTML = "Invalid timer setting!";
return;
}
qNums.push(wrapFunction(countDown, this, [sec]));
while (qNums) {
qNums.shift()();
}
}
function countDown(sec) {
var sec = document.getElementById("data").value;
var ms = 100;
isRunning = true;
document.getElementById("timer").innerHTML = "";
document.getElementById("btn").innerHTML = "Ticking!";
var interval = setInterval(function () {
if (ms == 100) {
document.getElementById("timer").innerHTML = sec + ".00";
} else {
document.getElementById("timer").innerHTML = sec + "." + ms;
}
ms -= 10;
if (ms < 0) {
sec--;
ms = 100;
}
if (sec < 0) {
document.getElementById("data").value = "";
document.getElementById("btn").innerHTML = "Start";
document.getElementById("timer").innerHTML = "Countdown complete";
isRunning = false;
clearInterval(interval);
}
}, 100);
}
</script>
<body>
<h1>Timer</h1>
<label>Timer Duration: </label><input id="data" />
<button id="btn" onclick="countDown()">Start</button>
<p id="timer"></p>
</body>
</html>
q() is my awful attempt at trying to implement this. countDown() is the standalone implementation of the countdown, separate from this functionality.
EDIT: Why does the snippet not run my code but the browser does???? Not sure how to fix this
Good try, but each interval has no way of triggering the next one to start with a callback, and without that, they'll all run concurrently. Pass the q.shift()() in as a callback to the timer function which can be invoked when the timer runs out alongside clearTimeout, or write a loop and only run the 0-th timer if it exists.
Another problem: setTimeout is often mistaken to be perfectly accurate, but this is an incorrect assumption. The ms parameter only guarantees the timer will be invoked no sooner than the duration specified. The consequence of this is that it will accumulate drift. A more accurate approach is to use a date object to check the system's time.
Here's a proof-of-concept using the polling version:
const enqueueTimer = () => {
const sec = +els.data.value;
if (!Number.isInteger(sec)) {
els.timer.innerHTML = "Not a number!";
}
else if (sec < 0) {
els.timer.innerHTML = "Invalid timer setting!";
}
else {
timers.push({duration: sec * 1000});
}
};
const updateTimers = () => {
if (!timers.length) {
return;
}
const {duration, start} = timers[0];
const now = new Date();
if (!start) {
timers[0].start = now;
}
const elapsed = now - start || 0;
const remaining = duration - elapsed || 0;
const sec = remaining / 1000;
const ms = remaining % 1000;
els.timer.innerHTML = `${~~sec}.${("" + ms)
.slice(0, 2).padEnd(2)}`;
els.btn.innerHTML = "Ticking!";
if (elapsed >= duration) {
timers.shift();
if (timers.length) {
timers[0].start = new Date(start.getTime() + duration);
}
else {
els.data.value = "";
els.btn.innerHTML = "Start";
els.timer.innerHTML = "Countdown complete";
}
}
};
const els = {
btn: document.getElementById("btn"),
data: document.getElementById("data"),
timer: document.getElementById("timer"),
};
els.btn.addEventListener("click", enqueueTimer);
const timers = [];
setInterval(updateTimers, 100);
<h1>Timer</h1>
<label>Timer Duration: <input id="data" /></label>
<button id="btn">Start</button>
<p id="timer"></p>
If it bothers you that the interval always runs, feel free to save the interval id, add a clearInterval() on the id when all the timers expire and kick off a new interval when a fresh timer is created.

Pause and start JS countdown timer

I am trying to develop a centurion countdown timer for my website. It is a drinking game.
The way the timer works is: It is a 60 second countdown timer. Everytime the timer hits 0 it will +1 a shot counter and restart. It will do this 100 times.
The game is you must do 1 shot, every minute for 100 minutes. I am a beginner at JS and I am learning a lot, but I am seriously struggling to get this to work the way I want it to.
All I need is a "Start" Button, a "Pause" button and a "Reset" button but I can't seem to find a way to make these buttons work without messing the timer up.
Here is the HTML code:
<div class="inner">
<h1 class="heading alt">Centurions Timer</h1>
<p>1 Shot. Every Minute. 100 Minutes.</p>
<p>___________________________________</p>
<div id="timer">
<p id="seconds">60</p>
<p id="shots">0</p>
</div>
<input type="button" value="Start" onclick="timer()">
<input type="button" value="Pause" onclick="clearInterval(myTimer)">
</div>
and here is the JS code:
var seconds = 60;
var shots = 0;
var timer;
var c = 60;
function timer() {
timer = setInterval(myTimer, 1000)
}
function myTimer() {
document.getElementById("seconds").innerHTML = --c;
if (c == 0) {
shots = shots + 1;
c = 60;
}
document.getElementById("shots").innerHTML = shots;
}
If anyone could help me and show me what I am doing wrong and how I can make the code better, please do!
First, consider renaming either your method timer() or variable timer to disambiguate between the two.
Next, setInterval() returns an interval ID, which you store in timer.
clearInterval() takes the interval ID as the parameter, so try passing it the timer variable instead of myTimer (a function)
Little bit clean up needed. For clearInterval, u have to id of timer to clear
var seconds = 60;
var shots = 0;
var timer;
var c = 60;
function start() {
clearInterval(timer)
timer = setInterval(( ) =>{
updateUi()
}, 1000);
}
function pause() {
clearInterval(timer)
}
function updateUi() {
document.getElementById("seconds").innerHTML = --c;
if (c == 0) {
shots = shots + 1;
c = 60;
}
document.getElementById("shots").innerHTML = shots;
}
<div class="inner">
<h1 class="heading alt">Centurions Timer</h1>
<p>1 Shot. Every Minute. 100 Minutes.</p>
<p>___________________________________</p>
<div id="timer">
<p id="seconds">60</p>
<p id="shots">0</p>
</div>
<input type="button" value="Start" onclick="start()">
<input type="button" value="Pause" onclick="pause()">
</div>
You can also use Pub Sub model, to make code looks clean.
var seconds = 60;
var shots = 0;
var c = 60;
function Emitter() {
this.cb;
this.on = cb => {
this.cb = cb;
};
this.emit = () => {
this.cb && this.cb();
};
this.cancel = () => {
this.cb = null;
};
}
const emitter = new Emitter();
const tick = () => {
setInterval(() => {
emitter.emit();
}, 1000);
};
tick()
function start() {
emitter.on(updateUi);
}
function pause() {
emitter.cancel();
}
function updateUi() {
document.getElementById("seconds").innerHTML = --c;
if (c == 0) {
shots = shots + 1;
c = 60;
}
document.getElementById("shots").innerHTML = shots;
}
<div class="inner">
<h1 class="heading alt">Centurions Timer</h1>
<p>1 Shot. Every Minute. 100 Minutes.</p>
<p>___________________________________</p>
<div id="timer">
<p id="seconds">60</p>
<p id="shots">0</p>
</div>
<input type="button" value="Start" onclick="start()">
<input type="button" value="Pause" onclick="pause()">
</div>
<div class="inner">
<h1 class="heading alt">Centurions Timer</h1>
<p>1 Shot. Every Minute. 100 Minutes.</p>
<p>___________________________________</p>
<div id="timer">
<p id="minutes">100</p>
<p id="seconds">60</p>
<p id="shots">0</p>
</div>
<input type="button" value="START" onclick="start()">
<input type="button" value="PAUSE" onclick="pause()">
<input type="button" value="RESET" onclick="reset()">
</div>
Changed the onclick functions to something more meaningful. Added an extra button and some more logic to auto-stop when hitting the 100 minutes.
var seconds = 60,
minutes = 100,
shots = 0;
timer = "";
// this will just stop the timer, if you click start it will resume from where it left off
function pause() {
clearInterval(timer);
}
// resets seconds/minutes/shots, stops game
function reset() {
clearInterval(timer);
seconds = 60;
minutes = 100;
shots = 0;
timer = "";
document.getElementById("minutes").innerHTML = minutes;
document.getElementById("seconds").innerHTML = c;
document.getElementById("shots").innerHTML = shots;
}
// starts game from wherever it was left
function start() {
timer = setInterval(function() {
document.getElementById("seconds").innerHTML = c--;
if (c === 0) {
document.getElementById("minutes").innerHTML = --minutes;
// when 100 minutes are up, game will stop and reset
if (minutes === 0) {
reset();
}
shots++;
c = 60;
}
document.getElementById("shots").innerHTML = shots;
}, 1000)
}

Javascript timer not working..

Here is my code, please tell me where I've made a mistake so I can learn from it and hopefully get it working :).
Here is the html:
<input type="text" id="txt" />
<input type="button" value="Start Timer" onclick="startTimer()" />
And here is the javascript:
var Timer = 120;
var checkTimer = false;
var t;
function countDown(){
doucment.getElementById("txt").value = Timer;
Timer--;
t = setTimeout("countDown();", 1000);
}
function startTimer(){
if(!checkTimer){
checkTimer = true;
countDown();
}
else{
console.log("Error!");
}
}
Looking into your code in this Fiddle
Had me stumble across a few things,
The startTimer() in the onclick wasn't found.
doucment !== document as pointed out by Sterling Archer
The string eval could be changed to t = setTimeout(countDown, 1000); also pointed out by Sterling Archer
Now let's go to the solution.
HTML
<input type="text" id="txt" />
<!-- Removed the onclick attribute and added an ID for the eventListener -->
<input type="button" value="Start Timer" id="start" />
JS
//Event listener for the button. Same as the onClick, this one, however, does work.
document.getElementById("start").addEventListener("click", startTimer, false);
var Timer = 120;
var checkTimer = false;
var t;
function countDown() {
document.getElementById("txt").value = Timer;
Timer--;
t = setTimeout(countDown, 1000);
}
function startTimer() {
if (!checkTimer) {
checkTimer = true;
countDown();
} else {
console.log("Error!");
}
}
What I've done is:
I've added an event listener to counter the startTimer() "cannot be found" error
I've changed doucment to document
and I've changed your string eval to t = setTimeout(countDown, 1000);
Hope this helps!
You have a typo. You should have document.getElementById("txt") not doucment.getElementById("txt"). Try this:
var Timer = 120;
var checkTimer = false;
var t;
function countDown() {
document.getElementById("txt").value = Timer;
Timer--;
t = setTimeout("countDown();", 1000);
}
function startTimer() {
if (!checkTimer) {
checkTimer = true;
countDown();
} else {
console.log("Error!");
}
}
Update:
If you would like for the timer to stop at zero, you will need to add an if statement to see if the timer is greater than 0 before decrementing the timer again. That would look like this:
HTML:
<input type="text" id="txt" />
<input type="button" value="Start Timer" onclick="startTimer()" />
JS:
var Timer = 120;
var checkTimer = false;
var t;
function countDown() {
document.getElementById("txt").value = Timer;
if (Timer > 0){
Timer--;
}
t = setTimeout("countDown();", 1000);
}
function startTimer() {
if (!checkTimer) {
checkTimer = true;
countDown();
} else {
console.log("Error!");
}
}
Demo: https://jsfiddle.net/hopkins_matt/moks2oyb/
Further improvements could be made to this code, but this is meant to illustrate that your code will work once the errors are fixed.

How would I find the difference between two button clicks in milliseconds?

I'm trying to make a program that tests your reaction time, but I don't know how to measure the time between two events, like button clicks. Here's my code so far. Thanks in advance to anyone that can help.
<!DOCTPYE html>
<html>
<head>
<script>
var button = document.getElementById("reactionTester");
var start = document.getElementById("start");
function init() {
var startInterval/*in milliseconds*/ = Math.floor(Math.random() * 30) * 1000;
setTimeout(startTimer, startInterval);
}
function startTimer() {
/*start timer and then later use stopTimer() to stop the timer and find
the difference bettween both button clicks.*/
}
</script>
</head>
<body>
<form id="form">
<input type="button" id="reactionTester" onclick="stopTimer()">
<input type="button" value="start" id="start" onclick="init()">
</form>
</body>
</html>
var startTime;
function startButton() {
startTime = Date.now();
}
function stopButton() {
if (startTime) {
var endTime = Date.now();
var difference = endTime - startTime;
alert('Reaction time: ' + difference + ' ms');
startTime = null;
} else {
alert('Click the Start button first');
}
}
Bind your start and stop buttons to these functions.
DEMO
For getting the time that has passed, you'll always need a start_time and end_time. startTimer() should set a start_time variable (or something similarly named), and stopTimer() should set an end_time variable.
stopTimer() can then subtract the two times and you've got the number of milliseconds passed.
(JavaScript stores times in milliseconds, so oldTime - newTime = milliseconds passed.)
Edit: Example JSFiddle - http://jsfiddle.net/L3Xha/
var startTime, endTime;
// self-executing function
(function(){
// init the background to white
document.body.style.background = "white";
// reset the color of the BG after 3 seconds.
setTimeout(
function(){
document.body.style.background = "red";
startTime = Date.now();
}
, 3000);
$("#go").on("click", function(){
stopTime = Date.now();
$("#reflex").text(
"Your time was " + (stopTime - startTime) + "ms."
);
});
})();
Keep track of the time of the first click, and on the second click, display the difference between now and the first click.
var start;
$('button').click(function() {
if (undefined === start) {
start = new Date().getTime();
return;
}
alert('Time difference is:' + (new Date.getTime() - start));
});
To measure millseconds between two button clicks, log timestamps in javascript
First Button:
document.getElementById('submit-button1').onclick = function() {
console.log(new Date().getTime()); //1388696290801
}
Second Button:
document.getElementById('submit-button2').onclick = function() {
console.log(new Date().getTime()); //1388696292730
}
You don't need a form, you just need buttons, you don't need intervals either. You also don't need jQuery.
<!DOCTPYE html>
<html>
<head>
<script>
var startTime, running;
function startStop() {
if (running) {
var timeTaken = Date.now() - startTime;
running = false;
console.log("Time: " + timeTaken);
}
else {
running = true;
startTime = Date.now();
}
}
</script>
</head>
<body>
<button onclick="startStop();">Start/Stop</button>
</body>
</html>
Edit
Date.now() is probably faster.

timer using javascript

I want implement timer using java script.I want to decrement timer with variation of interval.
Example.Suppose my timer starts at 500 .
I want decrement timer depending on the level such as
1. 1st level timer should decrement by 1 also decrement speed should be slow.
2.2nd level timer should decrement by 2 and decrement speed should be medium
3.3rd level timer should decrement by 3 and decrement speed should be fast
I can create timer using following code:
<script type="text/javascript">
var Timer;
var TotalSeconds;
function CreateTimer(TimerID, Time)
{
TotalSeconds=Time;
Timer = document.getElementById(TimerID);
TotalSeconds = Time;
UpdateTimer();
setTimeout("Tick()", 1000);
}
function Tick() {
TotalSeconds -= 10;
if (TotalSeconds>=1)
{
UpdateTimer();
setTimeout("Tick()", 1000);
}
else
{
alert(" Time out ");
TotalSeconds=1;
Timer.innerHTML = 1;
}
}
But i call this CreateTimer() function many times so its speed is not controlling because i call it many times.
Couple of points:
You've used all global variables, it's better to keep them private so other functions don't mess with them
Function names starting with a captial letter are, by convention, reserved for constructors
The function assigned to setTimeout doesn't have any public variables or functions to modify the speed while it's running so you can only use global variables to control the speed. That's OK if you don't care about others messing with them, but better to keep them private
The code for UpdateTimer hasn't been included
Instead of passing a string to setTimeout, pass a function reference: setTimeout(Tick, 1000);
Anyhow, if you want a simple timer that you can change the speed of:
<script>
var timer = (function() {
var basePeriod = 1000;
var currentSpeed = 1;
var timerElement;
var timeoutRef;
var count = 0;
return {
start : function(speed, id) {
if (speed >= 0) {
currentSpeed = speed;
}
if (id) {
timerElement = document.getElementById(id);
}
timer.run();
},
run: function() {
if (timeoutRef) clearInterval(timeoutRef);
if (timerElement) {
timerElement.innerHTML = count;
}
if (currentSpeed) {
timeoutRef = setTimeout(timer.run, basePeriod/currentSpeed);
}
++count;
},
setSpeed: function(speed) {
currentSpeed = +speed;
timer.run();
}
}
}());
window.onload = function(){timer.start(10, 'timer');};
</script>
<div id="timer"></div>
<input id="i0">
<button onclick="
timer.setSpeed(document.getElementById('i0').value);
">Set new speed</button>
It keeps all its variables in closures so only the function can modify them. You can pause it by setting a speed of zero.
Hope, this could be helpful:
<html>
<head>
<script type="text/javascript">
function showAlert()
{
var t=setTimeout("alertMsg()",5000);
}
function alertMsg()
{
alert("Time up!!!");
}
</script>
</head>
<body>
<form>
<input type="button" value="Start" onClick="timeMsg()" />
</form>
</body>
</html>
Check this demo on jsFiddle.net.
HTML
<div id="divTimer">100</div>
<div id="divDec">1</div>
<div id="divSpeed">100</div>
<input id="start" value=" Start " onclick="javaScript:start();" type="button" />
<input id="stop" value=" Stop " onclick="javaScript:stop();" type="button" /><br/>
<input id="inc" value=" Increase " onclick="javaScript:increase();" type="button" />
<input id="dec" value=" Decrease " type="button" onclick="javaScript:decrease();"/>​
JavaScript
var handler;
function start() {
handler = setInterval("decrementValue()", parseInt(document.getElementById('divSpeed').innerHTML, 10));
}
function stop() {
clearInterval(handler);
}
function decrementValue() {
document.getElementById('divTimer').innerHTML = parseInt(document.getElementById('divTimer').innerHTML, 10) - parseInt(document.getElementById('divDec').innerHTML, 10);
}
function increase() {
document.getElementById('divDec').innerHTML = parseInt(document.getElementById('divDec').innerHTML, 10) + 1;
document.getElementById('divSpeed').innerHTML = parseInt(document.getElementById('divSpeed').innerHTML, 10) + 200;
stop();
decrementValue();
start();
}
function decrease() {
document.getElementById('divDec').innerHTML = parseInt(document.getElementById('divDec').innerHTML, 10) - 1;
document.getElementById('divSpeed').innerHTML = parseInt(document.getElementById('divSpeed').innerHTML, 10) - 200;
stop();
decrementValue();
start();
}​
Hope this is what you are looking for.

Categories