iClicks++

by rocktronica

HTML

<p>
    <strong id="clicks">0</strong>
    times w/in
    <strong id="duration">00:00:00</strong>.
</p>
<p>
    <strong>Average</strong>: <span id="average">...</span>
</p>

<p>
    <input type="button" value="Start" id="btnStart" /> &nbsp;
    <input type="button" value="Finish" id="btnFinish" disabled />
</p>

<ul id="archive"></ul>

CSS

*{padding:0;margin:0;font-size:inherit;}
body {
    font: 16px/22px sans-serif;
    margin: 30px 20px;
    background: #222;
    color: #eee;
}
p { margin:0 0 18px; }
ul { padding-left: 20px; color: #666; font-size: 14px; }
small { font-size: 11px; }

JavaScript

// I suppose this is a variation of a lap timer. Not smart enough to know what exactly to call it.
// Tried to keep the JS sparse. Pardon the brevity, nested functions, and lack of legacy support.

var iClicks = 0,
    iStartTimestamp = 0,
    iTotalSeconds = 0,
    sAverage = "...";

var btnStart = document.getElementById("btnStart"),
    btnFinish = document.getElementById("btnFinish"),
    clicks = document.getElementById("clicks"),
    duration = document.getElementById("duration"),
    average = document.getElementById("average");

function friendlyTime(iSeconds) {
    var iMinutes = 0, iHours = 0;
    function pad(i) { return ("0"+i).slice(-2); }
    if (iSeconds >= 60) {
        iMinutes = Math.floor(iSeconds / 60);
        if (iMinutes >= 60) {
            iHours = Math.floor(iMinutes / 60);
            iMinutes = iMinutes - (iHours * 60);
            iSeconds = iSeconds - (iHours * 60 * 60);
        }
        iSeconds = iSeconds - (iMinutes * 60);
    }
    return pad(iHours) + ":" + pad(iMinutes) + ":" + pad(iSeconds);
}

function update(bUpdateSeconds) {
    if (bUpdateSeconds !== false) {
        iTotalSeconds = Math.floor(+new Date() / 1000) - iStartTimestamp;
    }
    clicks.innerHTML = iClicks;
    duration.innerHTML = friendlyTime(iTotalSeconds);
    sAverage = (iTotalSeconds === 0) ? "..." : "Once every " + Math.round(iTotalSeconds / iClicks) + " seconds";
    average.innerHTML = sAverage;
}

var cycle;

btnStart.addEventListener("click", function(e) {
    if (iClicks === 0) {
        btnStart.setAttribute("value", "Increment");
        btnFinish.removeAttribute("disabled");
        iStartTimestamp = Math.floor(+new Date() / 1000);
        cycle = setInterval(update, 1000);
    }
    iClicks++;
    console.log(iClicks + " in " + friendlyTime(iTotalSeconds));
    update(false);
});

btnFinish.addEventListener("click", function(e) {
    document.getElementById("archive").innerHTML = (function(){
        var sHtml =...