stefanplc
stefanplc

Reputation: 439

jQuery - load multiple files and then trigger an event

I'm trying to write code where if File A, B and C are loaded, an animation occurs. Right now I'm using the following code, but I was wondering if there isn't a simpler version to do this:

$(document).ready(function(){
    $("#file_A").load(function(){
        $("#file_B").load(function(){
            $("#file_C").load(function(){
            <!-- my animation script -->
            });
        });
    });    
});

This code though, doesn't really work for all situations. I would like something along the lines:

$(document).ready(function(){
    $("#file_A, #file_B, #file_C").load(function(){
    <!-- my animation script -->
    });    
});

Where basically I list all of the files I want to wait for to load and once that finishes, I start my animation script.

Thank you very much in advanced for any help!

Upvotes: 7

Views: 4028

Answers (3)

Sarsaparilla
Sarsaparilla

Reputation: 6670

One major problem with the $.load(X, function() {$.load(Y, ...)}); is that the files are loaded sequentially. Promises allow the browser to load the files in parallel. Without promises you'll need to use a counter, like:

var counter = 3;
$.load(X, onComplete);
$.load(Y, onComplete);
$.load(Z, onComplete);

function onComplete() {
  if (--counter == 0) //start animation
}

Upvotes: 0

Konstantin
Konstantin

Reputation: 3696

$.when( $("#file_A").load(function(){ <!-- only assignments -->  }),
        $("#file_B").load(function(){ <!-- only assignments -->  }),
        $("#file_C").load(function(){ <!-- only assignments -->  })
).then(function{ <!-- all files loaded -->  
                 <!-- my animation script -->  });    

Upvotes: 7

Viktor
Viktor

Reputation: 65

There is a way using Deferred objects and promises.

Let's asume you have two dererred objects, def1 and def2. Then you could use the following sintax:

$.when(def1, def2).then(callback)

Which mean, that once the .resolve() method would be applied to both deferreds, jQuery will execute the callback.

$.ajax it's an example of a defferred object. So you could set type:get (which converts the ajax request into a .load equivalent) on the request an passed them directly in $.when instruction.

You cannot do the same using .load() directly, because .load() does not return a deferred object, but jQuery.

Despite of that, .load() have a callback in its sintax sugar. So we can take advantage of it, doing the following:

(function(){

   // We first create the deferreds
   var def1 = $.Deferred();
   var def2 = $.Deferred();
   ...
   var defN = $.Deferred();

   // Then asociate them to load endings, executing .resolve in callbacks
   $('#1').load('path_to_file_1', function() {def1.resolve()});
   $('#2').load('path_to_file_2', function() {def2.resolve()});
   ...
   $('#N').load('path_to_file_N', function(){defN.resolve()});

   // And finally we handle all .resolve() invocations at once.
   $.when(def1, def1, ... , defN).done(function(){
      // Start your animation here.
   });

}());

Upvotes: 1

Related Questions