styler
styler

Reputation: 16481

Having multiple imageLoaded calls on 1 page and making sure each call is complete before progressing

I have 3 sections on my page that contain lots of images of various sizes, what I need to do is make sure each of these 3 sections images have completely loaded before I continue with applying any transitions etc like fading the sections in etc.

I think I know what I need to do but I'm not sure to execute it. I need to create a deferred object that monitors each of these calls when complete resolve the deferred object and then run a deferred.when or deferred.done method, does that sound like it could be right? As I say I'm just not sure how to do this?

I'm using the imagesLoaded plugin and my code currently looks something like this:

JS

    $(function () {


    var def1 = $.Deferred();
    var def2 = $.Deferred();
    var def3 = $.Deferred();
    var def = $.when(def1, def2, def3);


    $('.set1').imagesLoaded(function () {
        console.log('Set 1 ready');

        def1.resolve();
    });

    $('.set2').imagesLoaded(function () {
        console.log('Set 2 ready');

        def2.resolve();
    });

    $('.set3').imagesLoaded(function () {
        console.log('Set 3 ready');

        def3.resolve();
    });


    def.done(function () {
        console.log('ready');
    });

});

JS Fiddle http://jsfiddle.net/dkzrv/1/

Upvotes: 0

Views: 80

Answers (1)

jcbelanger
jcbelanger

Reputation: 549

$(function () {

function loadImages(selector) {
    var dfd = $.Deferred();

    /*
    ...do work to load images...
    if success,  dfd.resolve()/dfd.resolveWith(...)
    if failure,  dfd.reject()/dfd.rejectWith(...)
    to indicate progress, dfd.notify()/dfd.notifyWith(...)
    */

    $(selector).imagesLoaded(function () {
        var setResult = "dummy data";
        dfd.resolve(setResult);
    });

    /*
    If you return the dfd directly, 
    it can be canceled via .reject() from the outside.
    To allow outside canceling just return the dfd.
    */
    return dfd.promise();
}

//Run multiple deferreds in parallel and wait for all to complete with $.when
$.when(loadImages('.set1'), loadImages('.set2'), loadImages('.set3'))
    .done(function(set1Result, set2Result, set3Result) {
        //All resolved
    })
    .fail(function() {
        //One or more failed

        //If you want to know which one, 
        //you have to save a reference to each of 
        //the loadImages calls and determine through 
        //their individual .failure()'s            
    });

});

http://jsfiddle.net/dkzrv/4/

The $.when() function is a utility that wraps multiple deferreds into one. Because it returns a deferred of its own, you can call .done() and fail() and treat it as any other deferred.

For future reference, .then() is usually for controlling serial tasks and $.when() is for parallel tasks.

The loadImages() function is where you wrap the loadImages plugin in a deferred to make it more general.

Upvotes: 2

Related Questions