JSFiddle - React, Tailwind, and code Playground

by liyuankui

HTML

<script src="http://digitalbush.com/wp-content/uploads/2007/02/jqueryprogressbar.js"></script>
<style>
    /* progress bar container */
    #progressbar{
        border:1px solid black;
        width:200px;
        height:20px;
        position:relative;
        color:black; 
    }
    /* color bar */
    #progressbar div.progress{
        position:absolute;
        width:0;
        height:100%;
        overflow:hidden;
        background-color:#369;
    }
    /* text on bar */
    #progressbar div.progress .text{
        position:absolute;
        text-align:center;
        color:white;
    }
    /* text off bar */
    #progressbar div.text{
        position:absolute;
        width:100%;
        height:100%;
        text-align:center;
    }
</style>

<div id="progressbar"></div>
<input id="start" type='button' value='start' />

JavaScript

(function($){
    function run() {
        var x = 10,
            y = 10,
            z = 10,
            count = 0;

        /*
        This helper function implements a for loop using CPS. 'c' is
        the continuation that the loop runs after completion. Each
        'body' function must take a continuation parameter that it
        runs after doing its work; failure to run the continuation
        will prevent the loop from completing.
        */
        function foreach(init, max, body, c) {
            doLoop(init);
            function doLoop(i) {
                if (i < max) {
                    body(function(){doLoop(i+1);});
                }
                else {
                    c();
                }
            }
        }

        /*
        Note that each loop body has is own continuation parameter
        (named 'cx', 'cy', and 'cz', for clarity). Each loop passes
        the continuation of the outer loop as the termination
        continuation for the inner loop.
        */
        foreach(0, x, function(cx) {
            foreach(0, y, function(cy) {
                foreach(0, z, function(cz) {
                    count += 1;
                    $('#progressbar').reportprogress((100*(count))/(x*y*z));
                    /*
                    This is where the magic happens. It yields
                    control to the javascript event loop, which calls
                    the "next step of the foreach" continuation after
                    allowing UI updates.
                    */
                    setTimeout(cz, 1);
                }, cy);
            }, cx);
        }, function () {});
    }

    $('#start').click(run);
})(jQuery);