1

I have a page that displays a picture in high quality. The pictures typically take a while to load. I have a jQuery function that runs on load of the picture #image I want this function to pre-load other images 1 at a time in the order they will appear.

So: on if I am on the 1st picture, it should load picture 1 and display it, then pre-load/cache the second picture when pic1 is done. The pictures being loaded all have a caching header attached already. When pic2 is done loading, pic3 should begin loading. In case you are wondering, I have a cgi backend that is able to print things in loops and such.

So far I have the following working:

$('#image').load(function() {
 preLoad2 = new Image()
 preLoad2.src = "pic2"
})

I can then continue this with another function with the same $('#image').load(function() { } line, but how do I make it so the next picture doesn't begin loading until this one is completely loaded. I would prefer not to use a timed delay as that is not very accurate.

Here is what I have currently. I am using a bash cgi script in this example.

#set a loop counter
# variables will be refered to as $[var-name]
count=1
first=true
#loop through all images that need pre-loading
for file in *
  do
    #check if the picture matches the search criteria
    if [[ "$file" = *$lowerSearch* ]]
      then
        #create a js script
        echo "<script language=\"javascript\" type=\"text/javascript\">"
        echo "function load$count() {"
        echo " preLoad$count = new Image()"
        echo " preLoad$count.src = \"?loadFile=$file\""
        echo "}"
        #the first one of these functions should be bound to the main image load event
        if [ "$first" = 'true' ]
          then
            echo "document.getElementById('image').onload = load$count()"
        #the 2nd and on should be bound to the pre-load of the previous picture
        else
          echo " preLoad$last.onload = load$count()"
        #end if
        fi
        echo "</script>"
        #store the current count so that the next time through it can be used to call the last loaded picture
        last=$count
        first=false
        #add 1 to count
        count=$((count+1))
    #end if
    fi
#end loop
done

How this works: Loops through pictures. If the picture matches the search criteria then run the main code...otherwise skip loop. In the search criteria, it creates a js script that includes a function. the function loads the picture that the loop is currently referring to. It then creates an onLoad function that refers to the last picture pre-loaded and sets an onLoad event to it that runs the function just created.

I believe this question's answer is somewhat related to this question

Community
  • 1
  • 1
zggz12
  • 125
  • 3
  • 13
  • Why not just put the image in a container, set a loading.gif as the background and let the images load on their own? – elclanrs Nov 14 '13 at 02:58
  • @elclanrs I want to priorities the pictures so that it loads them in the order they will be used. Starting with the picture being displayed, which should load as fast as possible, while the next picture should be preLoaded as soon as the first picture is loaded. The picture after that should load next and it should continue going. – zggz12 Nov 14 '13 at 03:04
  • You can probably do it with deferreds, chaining the callbacks. http://api.jquery.com/category/deferred-object/ – elclanrs Nov 14 '13 at 03:10
  • I have made an edit to my question to show more of my code. I used many of the ideas from the below questions to create the pieces of code shown above – zggz12 Nov 14 '13 at 05:34

3 Answers3

1

First create JSON record of images like this

var imageRecord = ['image1.jpg',
                'image2.jpg',
                'image3.jpg',
                'image4.jpg',
                'image5.jpg'];

then create function to load image one after another

function loadAllImages(index){
  if( index >= imageRecord.length ){
    return;
  }
  //create image object
  var image = new Image();

  //add image path
  image.src = imageRecord[index];

  //bind load event
  image.onload = function(){
    //now load next image
    loadAllImages(index + 1);
  }

}

hope this small snippet will help you.

to understand whole concept of preload images using javascript, please visit http://zainultutorials.blogspot.in/2013/11/preload-images-using-javascript.html

Zainul Abdin
  • 835
  • 4
  • 10
0

In the past I've used something similar to this image preloader:

http://www.webreference.com/programming/javascript/gr/column3/index.html

The formatting on the code is weird but the code itself is good. After setting up that ImagePreloader "class" I used a method like this:

function preloadImages(imageSRCs){
var loadingMessage = $('<div/>').addClass('loading').html('<h1>LOADING</h1>');

// stay classy: tell the user you're loading images
$('#content').append(loadingMessage);

// this imgPreloader takes care of loading the images
imgPreloader = new ImagePreloader(imageSRCs, function(imgArr, numLoaded){
    if(this.nImages == numLoaded){
        loadingMessage.remove();
        //do whatever you want with the images here
        for(var i = 0; i < imgArr.length; i++){
            var pathIdPattern = new RegExp("[^/]+\\.");
            var imgName = pathIdPattern.exec(imgArr[i].src)[0];
            var imgId = imgName.substring(0, imgName.length-1);
            $('div#images').append($(imgArr[i]).hide().attr("id", imgId));
        }
    }else{
        loadingMessage.text('Sorry, there was a problem loading the site : / ');
        console.error("Only " + numLoaded + " of " + this.nImages + " images loaded successfully.");
    }
});}

Where the imageSRCs parameter was just a string array of the image paths. Maybe it's a more involved solution to what you're looking for but I hope it helps!

tylerargo
  • 1,000
  • 10
  • 13
0

if you have the images an array of urls you can do something like this: demo

<div id="cont"></div>
<script type="text/javascript">
function loadImagesInSequence(images) {
  if (!images.length) {
    return;
  }

  var img = new Image();

    //Remove if from the array list and return it to the variable
    var url = images.shift();

  img.onload = function(){ loadImagesInSequence(images) };
  img.src = url;

    $("#cont").append(img);
}

loadImagesInSequence(['http://www.nasa.gov/centers/goddard/images/content/433226main_Misti_ComaCluster.jpg',
'http://www.hdwallpapers.in/walls/cold_universe-wide.jpg',                     'http://scienceblogs.com/startswithabang/files/2013/05/chemical_composition_universe.jpeg']);
</script>

or if you have the image tags in your page you can go with something like this: demo

<img id="img1" src="http://miniontours.yzi.me/loading.gif" data-image="http://www.nasa.gov/centers/goddard/images/content/433226main_Misti_ComaCluster.jpg" />

<img id="img2" src="http://miniontours.yzi.me/loading.gif" data-image="http://www.hdwallpapers.in/walls/cold_universe-wide.jpg" />

<img id="img3" src="http://miniontours.yzi.me/loading.gif" data-image="http://scienceblogs.com/startswithabang/files/2013/05/chemical_composition_universe.jpeg" />
<script type="text/javascript">
var imgs = [];
$("img").each(function(){
    imgs.push({
        "ID": this.id,
        "src" : $(this).data("image")
              });
});


loadImagesInSequence(imgs);

function loadImagesInSequence(images) {
    if (!images.length) {
        return;
      }

  var img = images.shift();
  var url = img.src;

  img = $("#"+img.ID);
  img.load(function(){ loadImagesInSequence(images); });
  img.attr("src",url);
}
</script>
Juan
  • 4,910
  • 3
  • 37
  • 46