<html>
<head>
<style type="text/css">
#timer-name, #timer-h {
margin-left: 0.5em; }
#timer-name, #timer-s {
margin-right: 0.5em; }
#timer-h, #timer-m, #timer-s {
width: 2em; text-align: right; }
input[type="text"] {
border: 1px solid #222; }
#timers-table {
border: none; border-spacing: 2px; }
#timers-table td {
font: large sans-serif; color: #000;
padding: 1ex 1em; }
.timer-active {
background-color: #ded; }
.timer-fired {
background-color: #faa; }
.timer-suspended {
background-color: #bce; }
.timer-control {
font: small sans-serif; color: #238;
text-decoration: underline; cursor: pointer;
margin: 0ex 0.5em; }
</style>
<script type="text/javascript">
var timers = (function () {
var ready = false, timers = {}, nextId = 0, interval, tbody;
function newElement (tagName) {
return document.createElement(tagName);
}
function byId (id) {
return document.getElementById(id);
}
function parseInputInt (id) {
var value = byId(id).value;
return value != ""? parseInt(value, 10): 0;
}
function now () {
return (new Date()).getTime();
}
function init () {
interval = setInterval(update, 100);
tbody = byId("timers-table").tBodies[0];
ready = true;
}
function update () {
var id, timer, timeNow = now(), timeLeft, h, m, s;
for (id in timers) { if (timers.hasOwnProperty(id)) {
timer = timers[id];
if (timer.state == "active") {
timeLeft = timer.deadline - timeNow;
if (timeLeft > 0) {
h = Math.floor(timeLeft / 3600000);
m = Math.floor(timeLeft % 3600000 / 60000);
s = Math.floor(timeLeft % 60000 / 1000);
timer.row.cells[1].innerHTML =
(h < 10? "0" + h: h) + ":" +
(m < 10? "0" + m: m) + ":" +
(s < 10? "0" + s: s);
}
else {
timer.state = "fired";
timer.row.className = "timer-fired";
timer.row.cells[1].innerHTML = "00:00:00";
}
}
}}
}
function add (name, duration) {
if (!ready) { init(); }
var row, cell, control;
row = tbody.insertRow(-1);
row.className = "timer-active";
row.insertCell(-1).innerHTML = name;
row.insertCell(-1).innerHTML = "––:––:––";
cell = row.insertCell(-1);
control = cell.appendChild(newElement("span"));
control.className = "timer-control";
control.innerHTML = "пауза";
control.onclick = (function (id) { return function () { suspend(id); }})(nextId);
control = cell.appendChild(newElement("span"));
control.className = "timer-control";
control.innerHTML = "удалить";
control.onclick = (function (id) { return function () { remove(id); }})(nextId);
timers[nextId++] = {
state: "active",
deadline: now() + duration,
row: row
};
}
function launch () {
var name = byId("timer-name").value;
var h = parseInputInt("timer-h");
var m = parseInputInt("timer-m");
var s = parseInputInt("timer-s");
var duration = h * 3600000 + m * 60000 + s * 1000;
if (isFinite(duration) && duration > 0) {
add(name, duration);
}
}
function suspend (id) {
var timer = timers[id];
switch (timer.state) {
case "active":
timer.row.className = "timer-suspended";
timer.remain = timer.deadline - now();
timer.state = "suspended";
break;
case "suspended":
timer.row.className = "timer-active";
timer.deadline = now() + timer.remain;
timer.state = "active";
break;
}
}
function remove (id) {
tbody.deleteRow(timers[id].row.rowIndex);
delete timers[id];
}
function removeAll () {
var id;
for (id in timers) { if (timers.hasOwnProperty(id)) {
tbody.deleteRow(timers[id].row.rowIndex);
delete timers[id];
}}
}
function removeFired () {
var id;
for (id in timers) { if (timers.hasOwnProperty(id)) {
if (timers[id].state == "fired") {
tbody.deleteRow(timers[id].row.rowIndex);
delete timers[id];
}
}}
}
return {
launch: launch,
removeAll: removeAll,
removeFired: removeFired
};
})();
</script>
</head>
<body>
Имя: <input type="text" id="timer-name" value="Вася">
Время: <input type="text" id="timer-h" value="0"> : <input type="text" id="timer-m" value="5"> : <input type="text" id="timer-s" value="0">
<input type="button" value="Добавить" onclick="timers.launch()">
<input type="button" value="Удалить завершенные" onclick="timers.removeFired()">
<input type="button" value="Удалить всё" onclick="timers.removeAll()"><br><br>
<table id="timers-table"><tbody></tbody></table>
</body>
</html>