Thursday, May 31, 2012

Preloading images with jQuery


I'm looking for a quick and easy way to preload images with JavaScript. I'm using jQuery if that's important.



I saw this here ( http://nettuts.com... ):




function complexLoad(config, fileNames) {
for (var x = 0; x < fileNames.length; x++) {
$("<img>").attr({
id: fileNames[x],
src: config.imgDir + fileNames[x] + config.imgFormat,
title: "The " + fileNames[x] + " nebula"
}).appendTo("#" + config.imgContainer).css({ display: "none" });
}
};



But, it looks a bit over-the-top for what I want!



I know there are jQuery plugins out there that do this but they all seem a bit big (in size); I just need a quick, easy and short way of preloading images!



Thanks! :-D


Source: Tips4all

12 comments:

  1. Quick and easy:

    function preload(arrayOfImages) {
    $(arrayOfImages).each(function(){
    $('<img/>')[0].src = this;
    // Alternatively you could use:
    // (new Image()).src = this;
    });
    }

    // Usage:

    preload([
    'img/imageName.jpg',
    'img/anotherOne.jpg',
    'img/blahblahblah.jpg'
    ]);


    Or, if you want a jQuery plugin:

    $.fn.preload = function() {
    this.each(function(){
    $('<img/>')[0].src = this;
    });
    }

    // Usage:

    $(['img1.jpg','img2.jpg','img3.jpg']).preload();

    ReplyDelete
  2. JP, After checking your solution, I was still having issues in Firefox where it wouldn't preload the images before moving along with loading the page. I discovered this by putting some sleep(5) in my server side script. I implemented the following solution based off yours which seems to solve this.

    Basically I added a callback to your jQuery preload plugin, so that it gets called after all the images are properly loaded.

    // Helper function, used below.
    // Usage: ['img1.jpg','img2.jpg'].remove('img1.jpg');
    Array.prototype.remove = function(element) {
    for (var i = 0; i < this.length; i++) {
    if (this[i] == element) { this.splice(i,1); }
    }
    };

    // Usage: $(['img1.jpg','img2.jpg']).preloadImages(function(){ ... });
    // Callback function gets called after all images are preloaded
    $.fn.preloadImages = function(callback) {
    checklist = this.toArray();
    this.each(function() {
    $('<img>').attr({ src: this }).load(function() {
    checklist.remove($(this).attr('src'));
    if (checklist.length == 0) { callback(); }
    });
    });
    };


    Out of interest, in my context, I'm using this as follows:

    $.post('/submit_stuff', { id: 123 }, function(response) {
    $([response.imgsrc1, response.imgsrc2]).preloadImages(function(){
    // Update page with response data
    });
    });


    Hopefully this helps someone who comes to this page from Google (as I did) looking for a solution to preloading images on Ajax calls.

    ReplyDelete
  3. Here's a tweaked version of the first response that actually loads the images into DOM and hides it by default.

    function preload(arrayOfImages) {
    $(arrayOfImages).each(function () {
    $('<img />').attr('src',this).appendTo('body').css('display','none');
    });
    }

    ReplyDelete
  4. this jquery imageLoader plugin is just 1.39kb

    usage:

    $({}).imageLoader({
    images: [src1,src2,src3...],
    allcomplete:function(e,ui){
    //images are ready here
    $(document).ready(function(){
    //your code - site.fadeIn() or something like that
    });
    }
    });


    there are also other options like whether you want to load the images synchronously or asychronously and a complete event for each individual image.

    ReplyDelete
  5. I have a small plugin that handles this.

    It's called waitForImages and it can handle img elements or any element with a reference to an image in the CSS, e.g. div { background: url(img.png) }.

    If you simply wanted to load all images, including ones referenced in the CSS, here is how you would do it :)

    $('body').waitForImages({
    waitForAll: true,
    finished: function() {
    // All images have loaded.
    }
    });

    ReplyDelete
  6. If you want to preload images without JQuery look at preload images in Javascript.

    ReplyDelete
  7. Thanks for this! I'd liek to add a little riff on the J-P's answer - I don't know if this will help anyone, but this way you don't have to create an array of images, and you can preload all your large images if you name your thumbs correctly. This is handy because I have someone who is writing all the pages in html, and it ensures one less step for them to do - eliminating the need to create the image array, and another step where things could get screwed up.

    $("img").each(function(){
    var imgsrc = $(this).attr('src');
    if(imgsrc.match('_th.jpg') || imgsrc.match('_home.jpg')){
    imgsrc = thumbToLarge(imgsrc);
    (new Image()).src = imgsrc;
    }
    });


    Basically, for each image on the page it grabs the src of each image, if it matches certain criteria (is a thumb, or home page image) it changes the name(a basic string replace in the image src), then loads the images.

    In my case the page was full of thumb images all named something like image_th.jpg, and all the corresponding large images are named image_lg.jpg. The thumb to large just replaces the _th.jpg with _lg.jpg and then preloads all the large images.

    Hope this helps someone.

    ReplyDelete
  8. This one line jQuery code creates (and loads) a DOM element img without showing it:

    $('<img src="img/1.jpg"/>');

    ReplyDelete
  9. you can load images in your html somewhere using css display:none; rule, then show them when you want with js or jquery

    don't use js or jquery functions to preload is just a css rule vs many lines of js to be executed

    ReplyDelete
  10. function preload(imgs) {
    $(imgs).each(function(index, value){
    $('<img />').attr('src',value).appendTo('body').css('display','none');
    });
    }
    .attr('src',value)
    not
    .attr('src',this)


    just to point it out :)

    ReplyDelete
  11. All hipsters wrote there own version, so here's mine. It appends a hidden div to the body and fills it with the required images. I wrote it in Coffee Script. Here's the Coffee, the normal js, and the compressed js.

    Coffee:

    $.fn.preload = () ->
    domHolder = $( '<div></div>' ).css 'display', 'none'
    $( 'body' ).append domHolder
    this.each ( i, e) =>
    domHolder.append( $('<img/>').attr('src', e) )


    Normal:

    (function() {

    $.fn.preload = function() {
    var domHolder,
    _this = this;
    domHolder = $('<div></div>').css('display', 'none');
    $('body').append(domHolder);
    return this.each(function(i, e) {
    return domHolder.append($('<img/>').attr('src', e));
    });
    };

    }).call(this);


    Compressed:

    function(){$.fn.preload=function(){var a,b=this;return a=$("<div></div>").css("display","none"),$("body").append(a),this.each(function(b,c){return a.append($("<img/>").attr("src",c))})}}.call(this);

    ReplyDelete
  12. This one works like a charm..

    JpreLoader

    :)

    ReplyDelete