Jquery Image Loader

Found a tutorial about image loading using Jquery written by Remy Sharp while trying to create the same function for company i am working at. Remy has publish the core script and here i will modify it to make it work for multiple images, and load in sequencing order.
Multiple Image Loading
First we create an HTML page which has list element with class “loading” which we’re going to define later in the CSS, the amount of the list element depend on how many images we need to put here, in this example i have 3 images.
<ul id="portfolio"> <li class="loading"></li> <li class="loading"></li> <li class="loading"></li> </ul>
Next we add CSS for “loading” class which contain the spinner animated gif, as the loading animation.
<style type="text/css">
ul#portfolio { margin:0; padding:0; }
ul#portfolio li { float:left; margin:0 5px 0 0; width:250px; height:250px; list-style:none; }
ul#portfolio li.loading { background: url(spinner.gif) no-repeat center center; }
</style>
and here is the javascript, i already put some comments, which explain what the block codes do. Dont forget to load the jquery core file before these block lines.
// DOM ready
$(function () {
// image source
var images = new Array();
images[0] = 'http://farm4.static.flickr.com/3293/2805001285_4164179461_m.jpg';
images[1] = 'http://farm4.static.flickr.com/3103/2801920553_656406f2dd_m.jpg';
images[2] = 'http://farm4.static.flickr.com/3248/2802705514_b7a0ba55c9_m.jpg';
// loop through matching element
$("ul#portfolio li").each(function(index,el){
// new image object
var img = new Image();
// image onload
$(img).load(function () {
// hide first
$(this).css('display','none'); // since .hide() failed in safari
//
$(el).removeClass('loading').append(this);
$(this).fadeIn();
}).error(function () {
$(el).remove();
}).attr('src', images[index]);
});
});
you can see the preview of what we did so far here
Create element programmaticaly
Because of sometimes we do not know how many images will be added there, so its better if we let the codes to create the element itself, as many as neccesary. First lets change the HTML codes and left the UL alone with no child.
<ul id="portfolio"></ul>
and we need to change the looping part of the javascript:
// loop through images
$(images).each(function(index,value){
// create the LI programatically
var list = $('<li id="portfolio_'+index+'"></li>').attr('class','loading');
// append the new LI to UL
$('ul#portfolio').append(list);
// current LI object
var curr = $("ul#portfolio li#portfolio_"+index);
// new image
var img = new Image();
// load image
$(img).load(function () {
$(this).css('display','none'); // since .hide() failed in safari
$(curr).removeClass('loading').append(this);
$(this).fadeIn();
}).error(function () {
$(curr).remove();
}).attr('src', value);
});
Whats the different?, well on the first part the loop is based on matching element, and load the image from the array based on the index of the element, here the loop is based on the images array, and create the LI element programmaticaly for each of them, and then load itself to the new LI element.
and here is the preview
Sequencing Image Load
At the both previous examples all the images are loaded almost at the same times, now we will make the next image loaded only after the previous ones loaded or could not loaded (error).
Here is the HTML block:
<div id="wrapper"></div>
and here are the final javascript codes:
// DOM Ready
$(function () {
// Image Sources
var images = new Array();
images[0] = 'http://farm4.static.flickr.com/3293/2805001285_4164179461_m.jpg';
images[1] = 'http://farm4.static.flickr.com/3103/2801920553_656406f2dd_m.jpg';
images[2] = 'http://farm4.static.flickr.com/3248/2802705514_b7a0ba55c9_m.jpg';
// images length
var max = $(images).length;
// at least 1 image exist
if(max>0)
{
// create the UL element
var ul = $('<ul id="portfolio"></ul>');
// append to div#wrapper
$(ul).appendTo($('#wrapper'));
// load the first image
LoadImage(0,max);
}
// function of loading image
// params: (int) index of image in array, (int) length of images array
function LoadImage(index,max)
{
// if current index is lower then max element (max-1)
if(index<max)
{
// create the LI, add loading class
var list = $('<li id="portfolio_'+index+'"></li>').attr('class','loading');
// append to UL
$('ul#portfolio').append(list);
// current LI
var curr = $("ul#portfolio li#portfolio_"+index);
// new image object
var img = new Image();
// image onload
$(img).load(function () {
$(this).css('display','none'); // since .hide() failed in safari
$(curr).removeClass('loading').append(this);
$(this).fadeIn('slow',function(){
// once the current loaded, trigger the next image
LoadImage(index+1,max);
});
}).error(function () {
// on error remove current
$(curr).remove();
// trigger the next image
LoadImage(index+1,max);
}).attr('src', images[index]);
}
}
});
What the changes we made?, we completely changed the load method. Here we use a function “LoadImage” to load the image one by one based on the index of the image as the parameter.
if(max>0)
{
// create the UL element
var ul = $('<ul id="portfolio"></ul>');
// append to div#wrapper
$(ul).appendTo($('#wrapper'));
// load the first image
LoadImage(0,max);
}
you probably knew what the code above does, it check if image sources at least has 1 image, if so then it create UL element, and append it to div with id=”wrapper”, and then load the first image.
$(this).fadeIn('slow',function(){
LoadImage(index+1,max);
});
once the current image has completely loaded we trigger the same function to load the next image
and here is the final preview.
Experiments
Take a look at my Flickr Photo Set, uses PHP Flickr API, and the Jquery Image Loader above.
Small Update
Small update about grabbing the images from the DOM instead of declare it manualy at the javascript codes, could be found here, thanks for commenting





it’s very wonderful
Thanks for this tutorial
Thanks for this great tutorial
Thank for the sharing
. It helped me a lot! I start to use jquery
Neilo here again,
Actually, on second thoughts, I do not need to load the list elements programatically as I know how many images there are.
This means I can have two classes with different sizes corresponding to my images. So, I just need help on how to load the images in sequence using html list elements used in the first part of the tutorial.
I’m guessing the solution is easier here than in my previous post!
Any help would be fantastic!
Thanks,
Neilo.
Hey There,
Great tutorial mate! I wonder if you could indulge a complete Javascript amateur here.
My problem is I want to create the list elements programatically, but my images are two different sizes (portrait & landscape). The loading .gif will not be centered using just the one “loading” class.
Is there any way around this?
Thanks,
Neilo.
Hi,
Great solution!
I wonder if is possible to integrate this kind of loader inside of JQuery Acordeon Menu… I have to build a Acordeon menu wich has large buttons with images.
The problem is, when loading the JQuery the images appear before the Acordeon build.
My code for acordeon:
var slideMenu=function(){
var sp,st,t,m,sa,l,w,sw,ot;
return{
build:function(sm,sw,mt,s,sl,h){
sp=s; st=sw; t=mt;
m=document.getElementById(sm);
sa=m.getElementsByTagName(‘li’);
l=sa.length; w=m.offsetWidth; sw=w/l;
ot=Math.floor((w-st)/(l-1)); var i=0;
for(i;i<l;i++){s=sa[i]; s.style.width=sw+'px'; this.timer(s)}
if(sl!=null){m.timer=setInterval(function(){slideMenu.slide(sa[sl-1])},t)}
},
timer:function(s){s.onmouseover=function(){clearInterval(m.timer);m.timer=setInterval(function(){slideMenu.slide(s)},t)}},
slide:function(s){
var cw=parseInt(s.style.width,'10');
if(cw<st){
var owt=0; var i=0;
for(i;iot){oi=Math.floor((ow-ot)/sp); oi=(oi>0)?oi:1; o.style.width=(ow-oi)+’px’}
owt=owt+(ow-oi)}}
s.style.width=(w-owt)+’px’;
}else{clearInterval(m.timer)}
}
};
}();
the correct url for the update that Remy sharp made is
(http://www.chazzuka.com/blog/?p=103)
also it includes example of what u all looking for.
Hi,
I was interested in “Small update about grabbing the images from the DOM” but couldn’t find anything cause of page error. Where may I find something about it? Thanks!
Hi,
I was interested in “Small update about grabbing the images from the DOM” but couldn’t find anything cause of page error. Where may I find something about it? Thanks!
P.S. great job
Thanks for this great tutorial