Script tag unsuccessful - javascript

This works broken apart in js fiddle but when using a script tag the clock no longer works (no longer calls js). I have tried text/javascript , adding the javascript version in a script above and my latest attempt was adding language.
How do i determine how a line of javascript is suppose to be used in a script tag? Is there any way to figure out what phrase is suppose to be used in order for this to work.
It was originally made on code pen and it shows the javascript version is 1.7 there but i cannot get this to work if i use a script tag for the life of me.
<script language="JavaScript">/**[minimum JS only to set current time and sound the chimes]**/
(function () {
"use strict";
let seconds = document.getElementById("second_time"),
munutes = document.getElementById("minute_time"),
hours = document.getElementById("hour_time"),
s,
m,
h,
S,
M,
H,
time;
/*[set the clock to correct time and let CSS handle the rest]*/
function windup() {
(time = new Date()),
(s = time.getSeconds()),
(m = time.getMinutes()),
(h = time.getHours()),
(S = s * 6),
(M = m * 6 + s / 10),
(H = h * 30 + 0.5 * m);
seconds.style.transform = "rotate(" + S + "deg)";
munutes.style.transform = "rotate(" + M + "deg)";
hours.style.transform = "rotate(" + H + "deg)";
console.log("windup: " + h + ":" + m + ":" + s);
tick.volume = chime.volume = 1;
}
setTimeout(windup, 0);
/*[main visibility API function]*/
// use visibility API to check if current tab is active or not
let vis = (function () {
let stateKey,
eventKey,
keys = {
hidden: "visibilitychange",
webkitHidden: "webkitvisibilitychange",
mozHidden: "mozvisibilitychange",
msHidden: "msvisibilitychange"
};
for (stateKey in keys) {
if (stateKey in document) {
eventKey = keys[stateKey];
break;
}
}
return function (c) {
if (c) document.addEventListener(eventKey, c);
return !document[stateKey];
};
})();
/*[HTML5 Visibility API]****************************************/
// check if current tab is active or not
vis(function () {
if (vis()) {
setTimeout(function () {
// tween resume() code goes here
windup();
console.log("tab is visible - has focus");
}, 300);
} else {
// tween pause() code goes here
console.log("tab is invisible - has blur");
tick.volume = chime.volume = 0.1;
}
});
// check if browser window has focus
let notIE = document.documentMode === undefined,
isChromium = window.chrome;
if (notIE && !isChromium) {
// checks for Firefox and other NON IE Chrome versions
$(window)
.on("focusin", function () {
// tween resume() code goes here
setTimeout(function () {
windup();
console.log("focus");
}, 300);
})
.on("focusout", function () {
// tween pause() code goes here
console.log("blur");
tick.volume = chime.volume = 0.1;
});
} else {
// checks for IE and Chromium versions
if (window.addEventListener) {
// bind focus event
window.addEventListener(
"focus",
function (event) {
// tween resume() code goes here
setTimeout(function () {
windup();
console.log("focus");
}, 300);
},
false
);
// bind blur event
window.addEventListener(
"blur",
function (event) {
// tween pause() code goes here
console.log("blur");
tick.volume = chime.volume = 0.1;
},
false
);
} else {
// bind focus event
window.attachEvent("focus", function (event) {
// tween resume() code goes here
setTimeout(function () {
windup();
console.log("focus");
}, 300);
});
// bind focus event
window.attachEvent("blur", function (event) {
// tween pause() code goes here
console.log("blur");
tick.volume = chime.volume = 0.1;
});
}
}
/*[end HTML5 Visibility API]************************************/
/*[hourly and quarterly chimes]*/
const tick = document.getElementById("tick");
const chime = document.getElementById("chime");
const sound_dir = "http://www.gerasimenko.com/sandbox/codepen/sounds/";
let bell,
tock = "tock.wav";
tick.src = sound_dir + tock;
function hourly_chime(n) {
console.log("plays left: " + n);
if (n === 0) {
return;
} else {
chime.pause();
chime.currentTime = 0;
chime.play();
n--;
setTimeout(function () {
hourly_chime(n);
}, 3000);
}
}
setInterval(function () {
(time = new Date()),
(s = time.getSeconds()),
(m = time.getMinutes()),
(h = time.getHours());
console.log("watch: " + h + ":" + m + ":" + s);
tick.play();
if (s === 0 && (m === 15 || m === 30 || m === 45)) {
bell = "ding-tone.wav";
chime.src = sound_dir + bell;
hourly_chime(m / 15);
} else if (s === 0 && m === 0) {
bell = "bell-japanese.wav";
chime.src = sound_dir + bell;
h > 12 ? (h = h - 12) : h;
hourly_chime(h);
}
}, 1000);
})();
</script>

Related

Javascript not able to make common functions for a prototype

I am trying to make timer in javascript using a prototype. Each time a new timer is created, a object of prototype is created. There are methods to increase time and print each second. The whole code snippet is as follows:
function Timer(elem) {
this.interval = null;
this.currentTime = {
sec: 0,
min: 0,
hr: 0
};
this.elem = elem;
};
Timer.prototype.start = function() {
var self = this;
if (!self.interval) {
self.interval = setInterval(update, 1000);
}
function update() {
incrementTime();
render();
}
function render() {
self.elem.innerText = getPrintableTime();
}
function incrementTime() {
self.currentTime["min"] += Math.floor((++self.currentTime["sec"]) / 60);
self.currentTime["hr"] += Math.floor(self.currentTime["min"] / 60);
self.currentTime["sec"] = self.currentTime["sec"] % 60;
self.currentTime["min"] = self.currentTime["min"] % 60;
}
function getPrintableTime() {
var text = getTwoDigitNumber(self.currentTime["hr"]) + ":" + getTwoDigitNumber(self.currentTime["min"]) + ":" + getTwoDigitNumber(self.currentTime["sec"]);
return text;
}
function getTwoDigitNumber(number) {
if (number > 9) {
return "" + number;
} else {
return "0" + number;
}
}
};
module.exports = Timer;
I have all methods in start function. The problem is that for each new object of Timer, new space for each method will be used which is very inefficient. But when I try to put methods outside of start function, they lose access to self variable. You can see that there is setInterval function used which will be calling these methods per second. I cannot use this also as this will be instance of Window in subsequent calls.
How can I solve this situation by only keeping one instance of all the interior methods?
You don't need to have all methods in the start function. Yes, for each new Timer instance, new space for each function will be used, but that is necessary when you want to work with setInterval as you need a function which closes over the instance. However, you need only one such closure, the other methods can be standard prototype methods.
function getTwoDigitNumber(number) {
return (number > 9 ? "" : "0") + number;
}
function Timer(elem) {
this.interval = null;
this.currentTime = {
sec: 0,
min: 0,
hr: 0
};
this.elem = elem;
};
Timer.prototype.start = function() {
var self = this;
if (!this.interval) {
this.interval = setInterval(function update() {
self.incrementTime();
self.render();
}, 1000);
}
};
Timer.prototype.render() {
this.elem.innerText = this.getPrintableTime();
};
Timer.prototype.incrementTime = function() {
this.currentTime.sec += 1;
this.currentTime.min += Math.floor(this.currentTime.sec / 60);
this.currentTime.hr += Math.floor(this.currentTime.min / 60);
this.currentTime.sec = this.currentTime.sec % 60;
this.currentTime.min = this.currentTime.min % 60;
};
Timer.prototype.getPrintableTime = function() {
var text = getTwoDigitNumber(this.currentTime.hr) + ":"
+ getTwoDigitNumber(this.currentTime.min) + ":"
+ getTwoDigitNumber(self.currentTime.sec);
return text;
};
module.exports = Timer;
Btw, regarding your incrementTime pattern, you should have a look at How to create an accurate timer in javascript?.
You can use apply to use functions defined outside of prototype with correct this context.
function Timer(elem) {
this.interval = null;
this.currentTime = {
sec: 0,
min: 0,
hr: 0
};
this.elem = elem;
};
function update() {
incrementTime.apply(this);
render.apply(this);
}
function render() {
this.elem.innerText = getPrintableTime.apply(this);
}
function incrementTime() {
this.currentTime["min"] += Math.floor((++this.currentTime["sec"]) / 60);
this.currentTime["hr"] += Math.floor(this.currentTime["min"] / 60);
this.currentTime["sec"] = this.currentTime["sec"] % 60;
this.currentTime["min"] = this.currentTime["min"] % 60;
}
function getPrintableTime() {
var text = getTwoDigitNumber(this.currentTime["hr"]) + ":" + getTwoDigitNumber(this.currentTime["min"]) + ":" + getTwoDigitNumber(this.currentTime["sec"]);
return text;
}
function getTwoDigitNumber(number) {
if (number > 9) {
return "" + number;
} else {
return "0" + number;
}
}
Timer.prototype.start = function() {
var self = this;
if (!self.interval) {
self.interval = setInterval(function() {
update.apply(self);
}, 1000);
}
};
document.addEventListener('DOMContentLoaded', function() {
var timer = new Timer(document.getElementById('timer'));
timer.start();
}, false);
<div id="timer"></div>
If I understand correctly, you're wanting to only create one interval.
One possible solution would be to create a static method and variable to manage the setInterval. I would note that while this may be more performance friendly, the timers will always start and run on the same count...not from the moment each timer is created. (See example)
Of course, you could capture the current timestamp and calculate the elapsed time from there. But, that's another thread ;)
function Timer(elem) {
this.interval = null;
this.currentTime = {
sec: 0,
min: 0,
hr: 0
};
this.elem = elem;
};
Timer.subscribe = function(timer) {
Timer.subscribers = Timer.subscribers || [];
if (Timer.subscribers.indexOf(timer) === -1) {
Timer.subscribers.push(timer);
timer.update.call(timer);
}
Timer.checkInterval();
};
Timer.unsubscribe = function(timer) {
Timer.subscribers = Timer.subscribers || [];
if (Timer.subscribers.indexOf(timer) !== -1) {
Timer.subscribers.splice(Timer.subscribers.indexOf(timer), 1);
}
Timer.checkInterval();
};
Timer.checkInterval = function() {
if (!Timer.interval && Timer.subscribers.length > 0) {
Timer.interval = setInterval(function() {
Timer.subscribers.forEach(function(item) {
item.update.call(item);
});
}, 1000);
} else if (Timer.interval && Timer.subscribers.length === 0) {
clearInterval(Timer.interval);
Timer.interval = null;
}
};
Timer.prototype = {
start: function() {
Timer.subscribe(this);
},
stop: function() {
Timer.unsubscribe(this);
},
update: function() {
this.incrementTime();
this.render();
},
incrementTime: function() {
this.currentTime["min"] += Math.floor((++this.currentTime["sec"]) / 60);
this.currentTime["hr"] += Math.floor(this.currentTime["min"] / 60);
this.currentTime["sec"] = this.currentTime["sec"] % 60;
this.currentTime["min"] = this.currentTime["min"] % 60;
},
render: function() {
var self = this;
function getPrintableTime() {
var text = getTwoDigitNumber(self.currentTime["hr"]) + ":" + getTwoDigitNumber(self.currentTime["min"]) + ":" + getTwoDigitNumber(self.currentTime["sec"]);
return text;
}
function getTwoDigitNumber(number) {
if (number > 9) {
return "" + number;
} else {
return "0" + number;
}
}
this.elem.innerText = getPrintableTime();
}
};
/**
*
*/
var timers = document.getElementById('timers');
function addTimer() {
var el = document.createElement('div');
var tmr = document.createElement('span');
var btn = document.createElement('button');
var t = new Timer(tmr);
btn.innerText = 'Stop';
btn.onclick = function() {
t.stop();
};
el.appendChild(tmr);
el.appendChild(btn);
timers.appendChild(el);
t.start();
};
<div id="timers"></div>
<button onclick="addTimer()">Add Timer</button>

Adding simple delay to JavaScript code without using external libraries

A quick question, tell me please how to add delay to this code.
I guess it is super simple, but I am new to JavaScript.
I think the answer is somewhere in the beginning within the duration variable.
Here is JavaScript code:
var modern = requestAnimationFrame, duration = 400, initial, aim;
window.smoothScroll = function(target) {
var header = document.querySelectorAll('.aconmineli');
aim = -header[0].clientHeight;
initial = Date.now();
var scrollContainer = document.getElementById(target);
target = document.getElementById(target);
do {
scrollContainer = scrollContainer.parentNode;
if (!scrollContainer) return;
scrollContainer.scrollTop += 1;
}
while (scrollContainer.scrollTop == 0);
do {
if (target == scrollContainer) break;
aim += target.offsetTop;
}
while (target = target.offsetParent);
scroll = function(c, a, b, i) {
if (modern) {
var present = Date.now(),
elapsed = present-initial,
progress = Math.min(elapsed/duration, 1);
c.scrollTop = a + (b - a) * progress;
if (progress < 1) requestAnimationFrame(function() {
scroll(c, a, b, i);
});
}
else {
i++; if (i > 30) return;
c.scrollTop = a + (b - a) / 30 * i;
setTimeout(function() {scroll(c, a, b, i)}, 20);
}
}
scroll(scrollContainer, scrollContainer.scrollTop, aim, 0);
}
By the way it is a great pure JavaScript only code for scrolling on clicking.
var modern = requestAnimationFrame,
duration = 400,
initial,
aim,
delay = 1000;
window.smoothScroll = function(target) {
setTimeout(function() {
window.doSmoothScroll(target);
}, delay);
};
window.doSmoothScroll = function(target) {
var header = document.querySelectorAll('.navbar');
aim = -header[0].clientHeight;
initial = Date.now();
var scrollContainer = document.getElementById(target);
target = document.getElementById(target);
do {
scrollContainer = scrollContainer.parentNode;
if (!scrollContainer) return;
scrollContainer.scrollTop += 1;
}
while (scrollContainer.scrollTop === 0);
do {
if (target == scrollContainer) break;
aim += target.offsetTop;
}
while (target == target.offsetParent);
scroll = function(c, a, b, i) {
if (modern) {
var present = Date.now(),
elapsed = present - initial,
progress = Math.min(elapsed / duration, 1);
c.scrollTop = a + (b - a) * progress;
if (progress < 1) requestAnimationFrame(function() {
scroll(c, a, b, i);
});
} else {
i++;
if (i > 30) return;
c.scrollTop = a + (b - a) / 30 * i;
setTimeout(function() {
scroll(c, a, b, i);
}, 20);
}
};
scroll(scrollContainer, scrollContainer.scrollTop, aim, 0);
};

Starting Javascript intervals nonsynchronously and stop each after three runs

I have a function for letting blink a OpenLayer marker three times. The simplified version which only shows console messages:
function blink_three_times(layername){
var x = 0;
setTimeout(function() {
blink_in = setInterval(function() {
x = x+1;
if ( x === 3) {clearInterval(blink_in)};
console.log(layername + ' is visible');
}, 500);
}, 250);
blink_out = setInterval(function() {
if (x === 2) {clearInterval(blink_out)};
console.log(layername + ' is invisible');
}, 500);
};
It works fine, but if it is started multiple times before one has finished, the counter (x) exceeds 3 and the interval does not stop. How can I avoid that?
That is because you have funcions blink_in & blink_out in global scope. When you are calling it second time it overwrites the definitions of functions.
Define them using var to make them local.
var blink_in = setInterval(function() {..})
and
var blink_out = setInterval(function() {..})
DEMO
Your variables blink_in and blink_out are global ones so if you call the function multiple times they will override it and therefore cannot stop the interval properly.
Use them in your function scope by definining them with "var" in order to avoid the problem (see http://jsfiddle.net/cb0h8tst/)
function blink_three_times(layername){
var x = 0;
var blink_in, blink_out;
setTimeout(function() {
blink_in = setInterval(function() {
x = x+1;
if ( x === 3) {clearInterval(blink_in)};
console.log(layername + ' is visible');
}, 500);
}, 250);
blink_out = setInterval(function() {
if (x === 2) {clearInterval(blink_out)};
console.log(layername + ' is invisible');
}, 500);
};
Based on your last update question,
you could also make a more dynamic to keep track of the layers that are actually being blinked, a possible example
function Blinker(opt) {
var ts = {};
this.elementId = opt ? opt.elementId : undefined;
this.runs = (opt ? opt.runs : 3) || 3;
this.completed = (opt ? opt.completed : function() { }) || function() { };
this.start = function(arg) {
var timestamp = arg || this.elementId, that = this;
if (typeof ts[timestamp] !== 'undefined') {
console.log('Cannot run multiple times on same layer');
return;
}
ts[timestamp] = {
timestamp: timestamp,
count: 0,
element: document.getElementById(arg || this.elementId),
controller: this
};
setTimeout(function() {
ts[timestamp].showInterval = setInterval(that.setVisibility.bind(ts[timestamp], true), 500);
}, 250);
ts[timestamp].hideInterval = setInterval(this.setVisibility.bind(ts[timestamp], false), 500);
};
this.setVisibility = function(visible) {
this.element.style.visibility = visible ? 'visible' : 'hidden';
this.element.style.display = visible ? 'inherit' : 'none';
if (visible) {
this.count++;
}
if (!visible && this.count === 2)
{
clearInterval(this.hideInterval);
}
if (visible && this.count === 3)
{
clearInterval(this.showInterval);
this.controller.completed.apply(this.controller, [this.element.id]);
delete ts[this.timestamp];
}
};
}
var blinker = new Blinker({
elementId: 'blinker',
runs: 3,
completed: function(elementId) {
var log = document.getElementById('log');
log.innerHTML += '<p><strong>' + elementId + '</strong> has finished blinking</p>';
}
});
you could find the fiddle here: http://jsfiddle.net/q70w0kpx/

JS disappearing property

/*jslint browser: true, devel: true */
//*********************** Constants **************************
var FPS = 30;
var ANIMATIONOBJECTX = 1;
var ANIMATIONOBJECTY = 2;
var ANIMATIONOBJECTOPACITY = 3;
var ANIMATIONOBJECTWIDTH = 4;
var ANIMATIONOBJECTHEIGHT = 5;
var ANIMATIONOBJECTROTATION = 6;
//*********************** Rotation **************************
function setRotation(view, angle) {
"use strict";
view.css({
"-webkit-transform" : "rotate(" + angle + "deg)",
"-moz-transform" : "rotate(" + angle + "deg)",
"-ms-transform" : "rotate(" + angle + "deg)",
"-o-transform" : "rotate(" + angle + "deg)",
"transform" : "rotate(" + angle + "deg)"
});
view.angle = angle; //For getting the angle later
}
//*********************** Classes **************************
var AnimationObject = function (start, end, time, isSmooth, type, object) {
"use strict";
this.type = type;
this.stages = [];
var dif = end - start,
a,
b,
steps = time * FPS;
if (isSmooth) {
for (a = 0; a < steps; a += 1) {
if (a <= steps / 2) {
//Normal parabola
b = (2.0 / 9) * Math.pow(a, 2) * Math.pow(1.0 / time, 2);
} else {
//Upside down parabola
b = (-2.0 / 9) * Math.pow(a - (FPS * time), 2) * Math.pow(1.0 / time, 2) + 100;
}
this.stages.push(b / 100 * dif + start);
}
} else {
for (a = 0; a < steps; a += 1) {
this.stages.push(a / steps * dif + start);
}
}
//Applies animation value differently depending on type
if (type === ANIMATIONOBJECTX) {
this.applyAnimation = function (step) {
object.css("left", this.stages[step]);
};
} else if (type === ANIMATIONOBJECTY) {
this.applyAnimation = function (step) {
object.css("top", this.stages[step]);
};
} else if (type === ANIMATIONOBJECTOPACITY) {
this.applyAnimation = function (step) {
object.css("opacity", this.stages[step]);
};
} else if (type === ANIMATIONOBJECTWIDTH) {
this.applyAnimation = function (step) {
object.css("width", this.stages[step]);
};
} else if (type === ANIMATIONOBJECTHEIGHT) {
this.applyAnimation = function (step) {
object.css("height", this.stages[step]);
};
} else if (type === ANIMATIONOBJECTROTATION) {
this.applyAnimation = function (step) {
setRotation(object, this.stages[step]);
};
}
};
var AnimationManager = function (time, completionMethod) {
"use strict";
this.animationObjects = [];
this.time = time;
this.add = function (animationObject) {
this.animationObjects.push(animationObject);
};
this.completionMethod = completionMethod;
this.currentStage = 0;
this.maximumStage = this.time * FPS;
this.tick = function () {
this.currentStage += 1;
if (this.currentStage < this.maximumStage) {
setTimeout(this.tick.bind(this), 1000.0 / FPS);
} else {
//Set manager to nil in the completion method
this.completionMethod();
}
var i;
for (i = 0; i < this.animationObjects.length; i += 1) {
this.animationObjects[i].applyAnimation(this.currentStage);
}
};
//Call this to start
this.startAnimation = function () {
this.timer = setTimeout(this.tick.bind(this), 1000.0 / FPS);
};
};
//*********************** Animate Objects **************************
function animatePosition(object, manager, x, y, smooth) {
"use strict";
var curX = parseFloat(object.position().left),
curY = parseFloat(object.position().top);
manager.add(
new AnimationObject(curX, x, manager.time, smooth, ANIMATIONOBJECTX, object)
);
manager.add(
new AnimationObject(curY, y, manager.time, smooth, ANIMATIONOBJECTY, object)
);
}
function animateSize(object, manager, w, h, smooth) {
"use strict";
var curW = parseFloat(object.css("width")),
curH = parseFloat(object.css("height"));
manager.add(
new AnimationObject(curW, w, manager.time, smooth, ANIMATIONOBJECTWIDTH, object)
);
manager.add(
new AnimationObject(curH, h, manager.time, smooth, ANIMATIONOBJECTHEIGHT, object)
);
}
function animateOpacity(object, manager, opacity) {
"use strict";
var curO = parseFloat(object.css("opacity"));
manager.add(
new AnimationObject(curO, opacity, manager.time, false, ANIMATIONOBJECTOPACITY, object)
);
}
function animateRotation(object, manager, angle, smooth) {
"use strict";
console.log(object.angle);
if (object.angle === undefined) {
object.angle = 0;
}
manager.add(
new AnimationObject(object.angle, angle, manager.time, smooth, ANIMATIONOBJECTROTATION, object)
);
}
var view;
function doSomething() {
"use strict";
view = $("#test");
var manager;
view.html("animating");
var complete = function () {
view.html("complete");
manager = null;
setTimeout(doSomething, 100);
};
manager = new AnimationManager(Math.random() * 1.0, complete);
animatePosition(view, manager, Math.random() * 400, Math.random() * 500, true);
animateOpacity(view, manager, Math.random());
animateSize(view, manager, Math.random() * 500, Math.random() * 500, true);
animateRotation(view, manager, Math.random() * 360, Math.round(Math.random()));
manager.startAnimation();
}
That doSomething method at the bottom runs when I press a button. The animateRotation method detects that the object.angle is undefined and sets it to 0. During the animation, the setRotation is called and sets the object.angle to it's angle (and i can console.log it fine too). But when the complete function is called and the animation starts again, the object(view in the doSomething method).angle is reset back to undefined again. What is going on here?
As it is right now, view = $("#test"); runs everytime doSomething is called, which selects the same DOM node, but returns a different jQuery object everytime.
The easiest way of fixing this would be to do the following:
view = view || $("#test");
However you should probably refactor your code so that it doesn't rely on a global variable.
Once you will fix this, you will notice that an angle property will exist on the object, but it will still be undefined at the end of the animation. That's because the last time setRotation is called, angle is also undefined.

How to pause and resume a javascript timer [duplicate]

This question already has an answer here:
how to pause timer or freeze it and resume -> javascript
(1 answer)
Closed 9 years ago.
I have this timer which works fine, but i need to be able to pause and resume it after that. i would appreciate it if someone could help me.
<html>
<head>
<script>
function startTimer(m,s)
{
document.getElementById('timer').innerHTML= m+":"+s;
if (s==0)
{
if (m == 0)
{
return;
}
else if (m != 0)
{
m = m-1;
s = 60;
}
}
s = s-1;
t=setTimeout(function(){startTimer(m,s)},1000);
}
</script>
</head>
<body>
<button onClick = "startTimer(5,0)">Start</button>
<p id = "timer">00:00</p>
</body>
</html>
I simply can't stand to see setTimeout(...,1000) and expecting it to be exactly 1,000 milliseconds. Newsflash: it's not. In fact, depending on your system it could be anywhere between 992 and 1008, and that difference will add up.
I'm going to show you a pausable timer with delta timing to ensure accuracy. The only way for this to not be accurate is if you change your computer's clock in the middle of it.
function startTimer(seconds, container, oncomplete) {
var startTime, timer, obj, ms = seconds*1000,
display = document.getElementById(container);
obj = {};
obj.resume = function() {
startTime = new Date().getTime();
timer = setInterval(obj.step,250); // adjust this number to affect granularity
// lower numbers are more accurate, but more CPU-expensive
};
obj.pause = function() {
ms = obj.step();
clearInterval(timer);
};
obj.step = function() {
var now = Math.max(0,ms-(new Date().getTime()-startTime)),
m = Math.floor(now/60000), s = Math.floor(now/1000)%60;
s = (s < 10 ? "0" : "")+s;
display.innerHTML = m+":"+s;
if( now == 0) {
clearInterval(timer);
obj.resume = function() {};
if( oncomplete) oncomplete();
}
return now;
};
obj.resume();
return obj;
}
And use this to start/pause/resume:
// start:
var timer = startTimer(5*60, "timer", function() {alert("Done!");});
// pause:
timer.pause();
// resume:
timer.resume();
<p id="timer">00:00</p>
<button id="start">Start</button>
<button id="pause">Pause</button>
<button id="resume">Resume</button>
var timer = document.getElementById("timer");
var start = document.getElementById("start");
var pause = document.getElementById("pause");
var resume = document.getElementById("resume");
var id;
var value = "00:00";
function startTimer(m, s) {
timer.textContent = m + ":" + s;
if (s == 0) {
if (m == 0) {
return;
} else if (m != 0) {
m = m - 1;
s = 60;
}
}
s = s - 1;
id = setTimeout(function () {
startTimer(m, s)
}, 1000);
}
function pauseTimer() {
value = timer.textContent;
clearTimeout(id);
}
function resumeTimer() {
var t = value.split(":");
startTimer(parseInt(t[0], 10), parseInt(t[1], 10));
}
start.addEventListener("click", function () {
startTimer(5, 0);
}, false);
pause.addEventListener("click", pauseTimer, false);
resume.addEventListener("click", resumeTimer, false);
on jsfiddle
There are a whole load of improvements that could be made but I'm sticking with the code that the OP posted for the OP's comprehension.
Here is an extended version to give you further ideas on jsfiddle

Categories

Resources