3

i have some issue:

I have a resource-expensive operation (generating elements into DOM). Previously, i just called the operation at start, but when there are many elements to generate, the page just stucks a few seconds, with unclickable elements, etc.

So i put a over full screen which shows the progress of generation of elements. But somehow the browser (Chromium on Ubuntu 14.04) does not render the progress.

Similar code (because mine is too long to paste):

function generate() {
    var $content = $('#content'), $progress = $('#progress'), count = 0;
    for(var x = 1; x < 100; x++) {
        for(var y = 1; y < 100; y++) {
            $content.append('<span>' + x + '-' + y + '</span>'); // adding an element into DOM
            $progress.html('Generated elements: ' + count++ );
    }
}

Elements are generated correctly, but the number of generated elements is not changing (stays at 0, which is default in HTML code).

Is there a way how to force browser to repaint the $progress element?

user2864740
  • 60,010
  • 15
  • 145
  • 220
Tomáš Blatný
  • 892
  • 6
  • 20
  • Use `setTimeout` (and continue the work later in the callback) occasionally.. this will "yield" control back to the browser so that it can render the DOM updates, etc – user2864740 Jun 12 '14 at 22:50
  • It's effectively a "less extreme" form of [this problem](http://stackoverflow.com/questions/11155244/prevent-stop-running-script-when-loading-large-amounts-of-data) – user2864740 Jun 12 '14 at 22:52
  • 2
    http://stackoverflow.com/questions/15973089/javascript-settimeout-and-interface-freezing , http://stackoverflow.com/questions/11155244/prevent-stop-running-script-when-loading-large-amounts-of-data , http://stackoverflow.com/questions/22924196/waiting-in-javascript-beyond-wrapping-everything-in-settimeout – user2864740 Jun 12 '14 at 22:56

1 Answers1

1

This is untested but should get you pretty close to what you want.

   function generate() {
        var $content = $('#content'), $progress = $('#progress'), count = 0;
        for(var x = 1; x < 100; x++) {
            for(var y = 1; y < 100; y++) {
                (function(x, y) {
                        setTimeout(function() { 
                             $content.append('<span>' + x + '-' + y + '</span>');
                             $progress.html('Generated elements: ' + count++ );
                        }, Math.min(x + y, 100));
                })(x, y);
            }
        }
    }
Jack
  • 20,735
  • 11
  • 48
  • 48
  • Can you explain me the `Math.min(x + y, 100)` part? – Tomáš Blatný Jun 12 '14 at 23:30
  • 1
    You might not need that. Honestly, `100` will probably be fine. You'll have to test it. Since I didn't test this I wanted to ensure there was an offset, but also that if you changed your loop max that you wouldn't be waiting multiple seconds (or minutes) – Jack Jun 12 '14 at 23:35