1

I'm writing jQuery plugin and got a small problem -- cannot get a variable out of event's handler function. Take a look at my example for understanding:

(function( $ ){

  var methods = {

  init : function( options ) {

   var settings = $.extend( {
    'images': [['1.jpg'],['2.jpg'],['3.jpg']]
    }, options);

    var lastim=2; //just for test

    $.each(settings.images,function(event) {

    console.log(lastim); //Getting 2, Ok!

    img=new Image();
    img.src=settings.thumbPath+'/'+this[0];

    $(img).load(function(event)
            {      
            lastim=5;
            });
    });

    console.log(lastim); //Getting 2, expecting 5

   }};

$.fn.testSlider = function( method ) {
    if ( methods[method] ) {
      return methods[ method ].apply( this, Array.prototype.slice.call( arguments, 1 ));
    } else if ( typeof method === 'object' || ! method ) {
      return methods.init.apply( this, arguments );
    } else {
      $.error( 'No such method'+method );
    } 
};

})( jQuery );

How to get 5 in lastim variable after each function? Thank you in advance for helping!

Starmaster
  • 842
  • 1
  • 6
  • 9

3 Answers3

2

The problem is that the image isn't loaded when you do console.log(lastim);.

Use a deferred object or a callback.

Callback solution:

var methods = {
       loadImage: function(img, cb){
            $(img).load(cb);
       }

//.... etc

Use it like this:

methods.loadImage(img, function(){
    //image loaded
});

Or if you prefer deferred objects:

var dfd = $.Deferred(),
    promise = dfd.promise();

$(img).load(function(event){      
    dfd.resolve();
}).error(function(){
    dfd.reject();
});

promise.done(funciton(){
    //image loaded successfully
}).fail(function(){
    //image load error
});

Since you're using the deferred internally you could skip the promise and use the same methods on dfd.

Johan
  • 35,120
  • 54
  • 178
  • 293
1

Jquery.load is an async call. All code after this function will be executed regardless if Jquery.load has finished executing or not

$(img).load(function(event)
            {      
            lastim=5;
//DO ALL YOU WANT TO DO WITH YOUR VARIABLE HERE
            });
    });
eggward
  • 345
  • 1
  • 5
0

Your problem is: $(img).load(function(event) is asynch. When you exit the function, the callback function is not called yet.

Try:

(function( $ ){

  var methods = {

  init : function( options, callback ) { //Pass in a callback to receive value

   //Your code 

    $(img).load(function(event)
            {      
               lastim=5;
               if (typeof callback === "function"){
                     callback(lastim);
               }
            });
    });

   }};

var callback = function(lastim){
           //get callback value here
};

$.fn.testSlider = function( method ) {
    if ( methods[method] ) {
      return methods[ method ].apply( this, Array.prototype.slice.call( arguments, 1            ));
    } else if ( typeof method === 'object' || ! method ) {
      return methods.init.apply( this, arguments.concat([callback]);
    } else {
      $.error( 'No such method'+method );
    } 
};

})( jQuery );
Khanh TO
  • 48,509
  • 13
  • 99
  • 115