J_z
J_z

Reputation: 1083

Mass onLoad event freezes gif animation

I trying to make trivial load indicator, but in this case I'm stuck...

What we have

  1. #submit button
  2. when onClick to #submit, we fetch getJSON
  3. JSON data - is urls of images (might be 1-1000++ urls)
  4. for .each src we check onLoad
  5. and if its loaded we .append html to div #out

    <img id="load" src="load.gif" />
    <input id="submit" type="submit" value="submit" />
    <div id="out"></div>
    
    <script type="text/javascript">
    
    $('#submit').click(function()
    {
        $.getJSON('/data.json', function(data) {
    
            $.each(data, function(idx, img_src) {
    
                $('<img src="'+img_src+'">').load(function() {
                    $('#out').append('<img id="id'+idx+'" src="'+img_src+'">');
                });     
    
            });
    
        });
    
    });
    

In my example I don't show/hide load.gif, nvm for now, it shows the main problem - animation freezes when script works.

Tested on jQuery 1.7.1 + Chrome 17 (my app special for this browser)

Upvotes: 0

Views: 426

Answers (1)

jfriend00
jfriend00

Reputation: 707288

If you want to give the browser some cycles to do other things while loading a zillion images, you can do a small amount of work on a series of setTimeout() calls to allow some other things to happen between your chunks of work like this:

$('#submit').click(function() {
    $.getJSON('/data.json', function(data) {
        var i = 0;
        var out$ = $('#out'); 
        function appendNextImage() {
            // assumes data is an array of image URLs
            $('<img id="id'+i+'" src="'+data[i]+'">').load(function() {
                out$.append(this);
            });
            i++;
            if (i < data.length) {
                setTimeout(appendNextImage, 1);
            }
        }
        appendNextImage();
    });
});

I also changed your image creation so you append the DOM object that you've already created rather than making a second duplicate DOM object and put the $('#out') jQuery object in a closure so it isn't recreated every time.

Since I can't use jQuery's .each() in this coding structure, I had to manually iterate through your data. I assumed that it's an array of URLs.

Upvotes: 1

Related Questions