views:

83

answers:

2

Hay guys, I'm making a simple preload function

(function($) {
    $.fn.preload = function(settings) {

    var config = {
        before: function(){ return; },
        end: function(){ return; },
        after: function(a){ return; }
    };

    if (settings) $.extend(config, settings);

    var limit = this.length - 1;
    var counter = 0;

    settings.before();

    is_last_done = function(i){if (i == limit) return true;};

    this.each(function(i, src){
        $("<img>").attr("src", src).load(function(){

            if( a == counter ) settings.after();
            if(is_last_done(i)) settings.end(); // Last is done
            counter++;

        });
    });
    return this;
};
})(jQuery);

and calling it with

    img = ['a.jpg', 'b.jpg', 'b.jpg'];

    a = 1;

    $(img).preload({
        before: function(){ return; },
        end: function(){  },
        after: function(a){
            console.log('first done');
        }
    });

the problem is that the 'a' variable im passing to the 'after()' function is not being passed.

Inside the plugin i can access the variable with 'a', like on this line

if( a == counter ) settings.after();

The 'a' is availabe, however what if i want to name the a variable to something else? How do i access the argument of the after() function?

My code won't work anymore if i use this code

img = ['a.jpg', 'b.jpg', 'b.jpg'];

b = 1;

$(img).preload({
    before: function(){ return; },
    end: function(){  },
    after: function(b){
        console.log('first done');
    }
});

b doesnt get passed, any ideas?

Thanks

A: 

The variable is accessible on your nested functions, because it lives on the outer closure, you don't need the argument, you can simply use it:

var img = ['a.jpg', 'b.jpg', 'b.jpg'];
var b = 1;

$(img).preload({
    before: function(){ return; },
    end: function(){  },
    after: function(){
        // b is accessible here.
        console.log(b);
    }
});
CMS
What i want is be able to pass an int into the after() function and call it in my plugin no matter what its called.
dotty
A: 

If I understand correctly, you want to pass the iteration index to .after().

In your plugin, variable counter is used to track which step of the each() iteration you are in. This is unnecessary, as the first parameter to each is the loop index. See each in the documentation.

Also, function is_last_done() is not needed as the limit variable is in scope for the anonymous function called by each().

var limit = this.length - 1;

settings.before();

this.each(function(i, src){
    $("<img>").attr("src", src).load(function(){

        if (i == a) settings.after(i);
        if (i == limit) settings.end();

    });
});

Javascript is lexically scoped, so you do not have to do anything for a function to see variables declared in enclosing scopes. This is properly termed closure, and is described in this Mozilla article - Working with Closures.

Lachlan Roche
What i want is be able to pass an int into the after() function and call it in my plugin no matter what its called.
dotty