Kotanet
Kotanet

Reputation: 573

Jquery each() goes faster as load()

I have something like this

function loadImages(){
   var num = 1;
   $('.myElement').each(function(){
      var image = $("<img>").attr("src",mySrc).load(function(){
         if(num == 1){
            //do something - does not work
         }
      });       
      num++;
   });
}

And condition if(num == 1) does not work at all. I think, it's because while first image will be loaded, each() function still works and var num has some greater value, as my condition inside load() function goes to play... how can I fix it?

thx

full function code

function loadThumbs(imageCount){
var perc = 0;
var cache = [];
var thumbHolderWidth = 0;
var thumbHolderHeight = 0;
$('#thumbs').find(".image_thumb").each(function(enumThumb){
    if(enumThumb == 0){
          $(this).addClass('active');
    }                               
    var thisThumbSrc = $(this).find('img').attr('src');
    var smallim = $("<img>").attr("src",thisThumbSrc).load(function(){
        var thumbWidth = this.width;
        var thumbHeight = this.height;
        thumbHolderWidth = thumbHolderWidth + thumbWidth + 12;
        if(thumbHeight > thumbHolderHeight){
            thumbHolderHeight = thumbHeight;
        }
        });
        cache.push(smallim);

    var imgSrc = $(this).attr('bigimg');
    var im = $("<img>").attr("src",imgSrc).load(function(){
        if(enumThumb == 0){
            imWidth = this.width;
            imHeight = this.height;
            resizeOverlay(imWidth,imHeight,imgSrc);
        }
        perc = perc + (100/imageCount);
        var loaderWidth = Math.round(winWidth*perc/100);
        $('#thumb_loader').stop().animate({'width':loaderWidth+'px'});
        if(Math.round(perc) >= 100){
            $('#thumb_loader').animate({
                'height':'1px',
                'margin-top':'0px'
            },'fast',function(){
                $('#thumb_loader').addClass('loaded');
            });
        }
    });
    cache.push(im);
});
$('#images_overlay').find('#thumbs').css({
    'width':thumbHolderWidth+'px',
    'height':thumbHolderHeight+10+'px',
    'left':winWidth/2-thumbHolderWidth/2+'px'
})
$('#images_overlay').find('#thumbs').fadeIn();
}

Upvotes: 1

Views: 1514

Answers (4)

sabithpocker
sabithpocker

Reputation: 15566

The num you created is inside the scope of he function loadImages, once the each is finished the value of num wil be its maximum value. Now 'load' is an asynchronous thing, it gets called even after each is finished, at that time the value of 'num' should be maximum value. So for each call of load num is already at its max, and num==1 is never met

One solution can be like:

function loadImages(){
   $('.myElement').each(function(num){
     var image = $("<img>")
       .attr("src",mySrc)
       .load((function(numAlias){
         return function() {
            if(numAlias == 1){
            //do something - does not work
            }
          }
      })(num));       
   });
}

More Explanation on creating a sub-scope for each iteration can be found here, Return a function from the anonymous wrapper?

There can also be browser specific situation where load event might seem missed when setting src before attaching load. The problem was there before, not sure if its fixed, like there was bugs with Chrome for cahced images sometimes.

Adding src after load look like a reliable way.

var image = $("<img>").load(function(){
         if(num == 1){
            //do something - does not work
         }
      }).attr("src",mySrc); 

Upvotes: 0

Jon Jaques
Jon Jaques

Reputation: 4400

You're confusing the $.each function with the for loop. There is no need for the num variable or to increment it.

Here's an example of what you could to with all the features of the $.each function.

function loadImages(){
  $('.myElement').each(function(i, el){
    var image = $('<img>', {
      src: 'myimage'+i+'.jpg' // Loads a different image for each element.
    }).load(function(){
      image.hide().appendTo( $(el) ).fadeIn();  // Once loaded, appends image to .myElement and fades it in
    });
  });
}

Upvotes: 0

Siva Charan
Siva Charan

Reputation: 18064

It seems that you are not passing correct mySrc value.

mySrc should be something like YourImage.jpg

$('<img>').attr('src', mySrc).load(function() {  
  alert('Image Loaded');  
});

Why you need to use num++? You can get the index of the element with each function itself.

Upvotes: 0

Šime Vidas
Šime Vidas

Reputation: 185933

jQuery's each method provides the index to the callback function. You don't need a dedicated iterator variable.

$( '.myElement' ).each(function ( i ) {
    // use i here
});

Upvotes: 4

Related Questions