views:

429

answers:

5

Hi. Given this, which preloads an image:

$('<img />')
    .attr('src', 'source')
    .load(function(){
        $('.profile').append( $(this) );
        // Your other custom code
    });

do you know how to do the same but for several images?

I tried something like :

var img1 = new Image();
var img2 = new Image();
$(img1).attr('src', 'source1');
$(img2).attr('src', 'source2');

$(img1,img2).load(
 function () {
  //code after loading
 }
);

but it doesn't work!

Any ideas?

A: 

You need to create an array of elements:

$(img1,img2).load(

should be

$([img1, img2]).load(

It seems like overkill to do $(img1).attr('src', 'source1'); when you could do img1.src = 'source1';

Greg
+2  A: 

FINAL ATTEMPT

As far as I can tell you want to be able to tell when the image loads, and do it multiple times. The problem with the previous attempt, and your own code, is that the "load" handler is only applied AFTER the new image source has been set and executed. Please, try this on for size:

$(function () {
    var images = ['image1.jpg','image2.jpg' /* ... */ ];
    var imageObjects = [];
    var imagesToLoad = 0;

    for (i = 0, z = images.length; i < z; i++) {
        imageObjects[i] = new Image();
        imagesToLoad++;
        $(imageObjects[i])
            .load(function () {
                if (--imagesToLoad == 0) {
                    // ALL DONE!
                }
                // anything in this function will execute after the image loads
                var newImg = $('<img />').attr('src',$(this).attr('src'));
                $('.profile').append( $(newImg) ); // I assume this is the code you wanted to execute
            })
            .attr('src',images[i]);
            // Notice that the 'attr' function is executed AFTER the load handler is hooked
    }
});

[OLD] NEW ATTEMPT

var images = [ /* you get it by now */ ];
for (i=0,z=images.length;i<z;i++) {
    $('<img />')
        .attr('src', images[i])
        .load(function(){
            $('.profile').append( $(this) );
            // Your other custom code
        });
}

ORIGINAL POST

Idea taken from This Article

$(document).ready(function(){
    var images = ["image1.jpg","image2.jpg"];
    var loader = new Image();

    for (i=0,z=images.count;i<z;i++) {
        loader.src = images[i];
        // insert some code here to do something with the now-loaded image
    }
    // do something with the now-loaded images.
});

Alternatively,

var images = ["image1.jpg","image2.jpg"];
var loader = [];
$(document).ready(function(){

    for (i=0,z=images.count;i<z;i++) {
        loader[i] = new Image();
        loader[i].src = images[i];
        // insert some code here to do something with the now-loaded image
    }
    // do something with the now-loaded images, using the loader array
});
Dereleased
That doesn´t help me because I need to do something after all the images are loaded
Dimitri Wetzel
That obviously doesn't work! Nothing tells you that all the images are loaded when you do : // do something with the now-loaded images, using the loader array
Dimitri Wetzel
That's a comment. That's the point where you insert your own code. All I wrote was a loop. I have edited my response again to hopefully address the point I believe I had missed until then. Hope this helps.
Dereleased
I know thats a comment! I mean at the time you reach that point (where the comment is) nothing tells you that the images are all loaded!
Dimitri Wetzel
Did you bother at all to write what you wrote here? You know if I would want to read a google result I would have found it myself!
Dimitri Wetzel
Yes, I did write my own examples. I provided links as proof-of-concept. I am sorry they do not live up to your satisfaction, sir.
Dereleased
Just found your comment about wanting to realize a "final" loading event; is a counter out of the question? I have edited my "final attempt" to reflect a counter.
Dereleased
So, weird, that you got it now, it was exactly that what I was asking for. You obviously read my mind :-) Thanks!
Dimitri Wetzel
A: 
function myfun(){
  alert("h");
} 

var xlist = [ "source1", "source2", "source3" ];
var xload = 0;
$.each(xlist, function(){
    var srcImg = this;
    $('<img />')
       .attr('src', srcImg)
       .load(function(){
           xload++;
           $('.profile').append( $(this) );
           if (xlist.length==xload){

             // Your other custom code
             myfun();  

           }
       });
});

for comment: could simply be controlling the total amount of pictures loaded.

andres descalzo
" Your other custom code" will be repeated for each of the loads, no?
Dimitri Wetzel
yes, the ".append( $(this) );" refers to the "img" that is loading, and creates a "<img />" per "$.each"
andres descalzo
I think I was not clear. If "your other custom code" is an alert, and if I need to preload 10 images, the I will have 10 times the alert! Thats not what I want! I need to do one alert when all the images finished loading, which I think it won't work with the code you provide!
Dimitri Wetzel
It looks like you need to figure this out yourself then because your original question mentioned none of this. Good luck.
Stephen Delano
A: 

Load is triggered when you set the 'src' attribute. You must register the event before you set the 'src' attribute. Try this:

var img1 = new Image(); 
var img2 = new Image(); 
$([img1,img2]).load( function () { //code after loading } );
$(img1).attr('src', 'source1');
$(img2).attr('src', 'source2');

Hope this helps!

UPDATED

var images = [ /* you get it by now */ ];
for (i=0,z=images.length;i<z;i++) {
$('<img />')
  .load(function(){
    $('.profile').append( $(this) );
    // Your other custom code
  })  
  .attr('src', images[i]);
  /* you may also try to add .trigger('load') at the end to force it */
}

-Stephen

Stephen Delano
Tried, doesn't work. I think because as soon as you give one src the load is triggered!
Dimitri Wetzel
Updated for your new code
Stephen Delano
I think I was not clear. If "your other custom code" is an alert, and if I need to preload 10 images, the I will have 10 times then alert! Thats not what I want! I need to do one alert when all the images finished loading, which I think it won't work with the code you provide!
Dimitri Wetzel
Problem: load is notoriously unreliable.
Nosredna
A: 

I recently went through this nightmare. There are a couple StackOverflow questions where I mentioned the frustrating problems with the image load event.

One way that actually works cross-browser is to use a timer and watch both the image complete property (until it is true) and the image width property (until it is non-zero). Just spin through all your images until that pair of requirements is true for all of them.

Or you could try Luke Smith's solution.

Nosredna