Question

I'm trying to store my script that counts numbers starting from 23,000 to always continue to appear it's "live" and always counting using Web Storage. I've tried implementing this and so far, I can't seem to get it to work. What would be the best solution to get this to work and function to always count even when refreshing, etc? I've included my JS Fiddle and code below. Any help is kindly appreciated!!

EDIT: To clarify.. I'm trying to have a "live" counter always going no matter what when you go to the page, refresh it, whatever. It's just always going and getting bigger no matter what just like my script does.. However, everytime I refresh it starts back at 23,000.

HTML

<span id="liveNumbers">23,000</span>

JS

if(typeof(Storage)!=="undefined")
  {
       setInterval(function(){
       random = (Math.floor((Math.random()*2)+1));
       var plus = Math.random() < 0.5 ? 1 : 1;
       random = random * plus; 
       currentnumber = document.getElementById('liveNumbers');
       var curnum = parseInt(currentnumber.innerHTML.replace(",",""));

       document.getElementById('liveNumbers').innerHTML = 
           commaSeparateNumber(curnum + random);
       }, 3000);

       function commaSeparateNumber(val){
       while (/(\d+)(\d{3})/.test(val.toString())){
          val = val.toString().replace(/(\d)(?=(\d\d\d)+(?!\d))/g, "$1,");
       }
       return val;
     }
  }
else
  {
  // Sorry! No Web Storage support..
  }       
Was it helpful?

Solution

Here's my attempt: fiddle

The logic:

  • On first visit (no localStorage data) the counter is reset to 23000.
  • Counter runs while page is open.
  • When closing the page, the current counter value is stored together with the current timestamp (lastSessionEnd).
  • When user loads the page again, the time that has passed since he closed the page is translated into interval cycles which are passed to the randomRange function and added to the stored counter from the last session.

Here's the code:

if(window.localStorage) {
    //configs
    var updateInterval = 3000; //ms
    function randomRange() {
        return Math.floor(Math.random()*3)+1; // [1..3] range
    }


    var counter = +localStorage.getItem('counter');
    if (!counter) { //first load
        counter = 23000;
    } else { //simulate randomness that would have happened while the user was away from the page
        var lastSessionEnd = +localStorage.getItem('lastSessionEnd');
        for(var l = Math.floor((getUnixTimeStamp() - lastSessionEnd)*1000/updateInterval); l--;) {
            counter += randomRange();
        }
    }

    var liveNumbers = document.getElementById('liveNumbers'); //cache DOM query
    function refreshDisplay() {
        liveNumbers.innerHTML = commaSeparateNumber(counter);
    }
    refreshDisplay();
    setInterval(function() {
        counter += randomRange();
        refreshDisplay();
    }, updateInterval);

    function commaSeparateNumber(val) {
        while (/(\d+)(\d{3})/.test(val.toString())){
            val = val.toString().replace(/(\d)(?=(\d\d\d)+(?!\d))/g, "$1,");
        }
        return val;
    }

    function getUnixTimeStamp() {
        return Math.floor(Date.now()/1000);
    }

    window.addEventListener('beforeunload', function() {
        localStorage.setItem('counter', counter);
        localStorage.setItem('lastSessionEnd', getUnixTimeStamp());
    });
} else {
  // Sorry! No Web Storage support..
}

NOTE: this is not perfect, here are the caveats:

  • As it is done purely in the front-end, it is easily hackable by manipulating the localStorage. Don't use this for important stuff.
  • As it uses the localStorage API, if the user opens the page in more than one browser (or more than one computer/device), each one will have a different counter. Also, cleaning all personal data will reset the counter.
  • Finally, there's an interval cycle rounding error, it doesn't account for interrupted interval cycles. E.g. the user closes the page midway through an interval cycle, the next time he opens the page that half-cycle will be discarded and a new one starts. I believe this is a small detail which would take more effort to fix than it's worth, but I'll leave that decision and effort to you.
Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top