698

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!

20 Answers20

977

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();
James
  • 109,676
  • 31
  • 162
  • 175
  • Howcome this code doesn't work for me? Does it work for others? – Amit Aug 06 '10 at 20:32
  • 26
    Doesn't the image element need to be inserted into the DOM to ensure the browser caches it? – JoshNaro Aug 17 '10 at 15:33
  • 1
    @JoshNaro It does load them into the DOM at `$('')` – Iolo Feb 07 '11 at 12:10
  • 10
    I believe `$('')` just creates an image element in memory (see [link](http://api.jquery.com/jQuery/#jQuery2)). It looks like `'$('')` would actually create the element within a hidden DIV, because it is more "complicated". However, I don't think this is needed for most browsers. – JoshNaro Feb 11 '11 at 15:30
  • 2
    But how do you detect when all of that preloading has completed? – mheavers Aug 19 '11 at 14:18
  • @mheavers You don't have to detect it. Preloading is so the images are already loaded before they're shown. For example, a div with a background image that changes on hover. If you don't preload it, it has to load when you hover and it flashes a bit which isn't that nice. That's the purpose of preloading. But there is probably a way to detect when its all done. – Nathan Oct 12 '11 at 21:49
  • Another way is to load using standard HTML. Something like this:
    ...
    . Not 100% sure but I think that the body onload event gets called after all the images were loaded.
    – Alexis Wilke Jan 02 '12 at 01:21
  • 104
    That is a weird way of writing a jQuery plugin. Why not `$.preload(['img1.jpg', 'img2.jpg'])` ? – alex Jan 17 '12 at 02:56
  • This seemed to work for a short while for me in Opera. When I actually inserted the images (hidden) into the DOM, it worked fine. – Arve Systad Mar 27 '12 at 10:42
  • 12
    Make sure to call this inside `$(window).load(function(){/*preload here*/});` because that way all images in the document are loaded first, it's likely that they are needed first. – Jasper Kennis May 05 '12 at 15:35
  • 5
    Based on the following jsfiddle experiment I just did, this answer is perfectly valid. The load event will fire for the image even though it was not added to the document... However, you might also want to include a function that executes on the load event so you can do something with your images after they have loaded. http://jsfiddle.net/2cgFp/6/ – trusktr Jun 14 '12 at 00:53
  • 2
    I guess internally `$('')` uses `(new Image())` so why present it as the alternative? is there a situation where it will not work? – epeleg Jul 18 '12 at 11:13
  • 4
    FYI: `$(document.createElement('img'))` though more verbose, is slightly faster than `$('')` because jQuery doesn't have to parse the string and figure out whether it's a selector or an element to create. – Andrew Ensley Nov 12 '12 at 14:59
  • 1
    @mheavers - You can detect that it's done preloading like this... $('').attr('src', this).load(function() { /* it's loaded! */ }); – Alex K Nov 16 '12 at 16:26
  • 12
    @RegionalC - It may be a little safer to set the `load` event before setting the `src` just in case the image finishes loading before the load event is set? `$('').load(function() { /* it's loaded! */ }).attr('src', this);` – sparebytes Feb 04 '13 at 22:01
  • 1
    If anyone else cares, using `` inside ` – marcias Aug 20 '13 at 13:57
  • It's better not to use `this` but rather have `(ind, src)` parameters to the callback because `this` will lead to wrapping scalar values (e.g. strings) into objects, here is a piece from the JQuery documentation: The value can also be accessed through the this keyword, but Javascript will always wrap the this value as an Object even if it is a simple string or number value. – Meglio Jan 30 '14 at 08:05
  • @Meglio that doesn't make difference, since in JavaScript a string or a number is an object either way, e.g. `'foo'.length` will yell 3. – Gajus Aug 21 '14 at 15:35
  • Is there a way to do this with some delay? I am currently running into the problem that it is loading all these big images before the small more important images on my html are loaded (the ones I assigned via javascript) – John Feb 03 '15 at 03:45
  • @user3525295 Have you tried wrapping the preloading call (the usage, not the function) into jQuery's document ready function? – sage88 Feb 06 '15 at 16:51
  • what about using `link` element as mentioned [here](https://msdn.microsoft.com/en-us/library/dn265039%28v=vs.85%29.aspx) ? – Shaiju T Oct 13 '15 at 09:09
  • @John I could be wrong here, but doesn't the order specified determine what gets loaded first? Can't you just specify that it load the smaller ones first? – kojow7 Dec 31 '15 at 06:58
  • Is there any way to load images synchronously in order while preloading in this function? – Susen Maharjan Nov 15 '17 at 06:45
  • As of 2019, `$(window).on('load', function(){/*preload here*/});` – Alfred Wallace May 07 '19 at 15:53
  • And how can I use these images? I mean, where is the handle? – Ajowi Mar 08 '22 at 11:31
106

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');
    });
}
Dennis Rongo
  • 4,611
  • 1
  • 25
  • 25
  • 39
    `hide()` is more terse than `css('display', 'none')`. – alex Sep 22 '11 at 02:32
  • 6
    What's the advantage of inserting them into the DOM? – alex May 07 '13 at 21:56
  • I also would like to know the advantage of inserting them into the DOM. – jedmao Jul 03 '13 at 23:39
  • 11
    From my experience, preloading an image into the DOM makes the browser aware of its existence and for it to be properly cached. Otherwise, the image only exists in memory which only works for single page apps. – Dennis Rongo Jul 04 '13 at 18:00
  • 1
    Dennis Rongo. Appending images to the DOM fixed random re-loading on Chrome. Thanks! – tmorell Nov 07 '13 at 02:53
  • Is there a way to do this with some delay? I am currently running into the problem that it is loading all these big images before the small more important images on my html are loaded (the ones I assigned via javascript) – John Feb 03 '15 at 03:45
55

Use JavaScript Image object.

This function allows you to trigger a callback upon loading all pictures. However, note that it will never trigger a callback if at least one resource is not loaded. This can be easily fixed by implementing onerror callback and incrementing loaded value or handling the error.

var preloadPictures = function(pictureUrls, callback) {
    var i,
        j,
        loaded = 0;

    for (i = 0, j = pictureUrls.length; i < j; i++) {
        (function (img, src) {
            img.onload = function () {                               
                if (++loaded == pictureUrls.length && callback) {
                    callback();
                }
            };

            // Use the following callback methods to debug
            // in case of an unexpected behavior.
            img.onerror = function () {};
            img.onabort = function () {};

            img.src = src;
        } (new Image(), pictureUrls[i]));
    }
};

preloadPictures(['http://foo/picture.bar', 'http://foo/picture.bar', 'http://foo/picture.bar', 'http://foo/picture.bar'], function(){
    console.log('a');
});

preloadPictures(['http://foo/picture.bar', 'http://foo/picture.bar', 'http://foo/picture.bar', 'http://foo/picture.bar'], function(){
    console.log('b');
});
Gajus
  • 69,002
  • 70
  • 275
  • 438
  • 4
    *Do the right thing, use JavaScript Image object.* did you observe people doing the *wrong* thing in these answers? – alex May 07 '13 at 21:58
  • Brilliant code. Am I correct in thinking that this will fire the `onload` event even if the image is cached? (Because `img.onload` is declared first). This is what my tests showed. – Startec May 23 '14 at 10:06
  • 3
    @alex potentially, yeah. If the goal is to pre-load (which suggests an order of performance) then I'd prefer to see a raw JS option instead of jQuery dependent options. – Charlie Schliesser Jul 15 '14 at 23:57
  • I loved this solution but I just discovered that it doesn't work in my Firefox. Is it just me or are others having the same issue? – Gazillion Aug 20 '14 at 19:37
  • @Gazillion give more details. How do you define "not working"? What is the FF version? – Gajus Aug 20 '14 at 20:30
  • Sorry Gajus, just nothing happens. I get no error and the onload code does not get called. I'm running FF 31.0. I think it might be my implementation of it and will report back once I fix it. – Gazillion Aug 20 '14 at 20:39
  • @Gazillion Add the `onabort`, `onerror` callbacks. See if either is triggered. – Gajus Aug 20 '14 at 21:08
  • Have a look at a more complete example using the same technique, http://fragged.org/preloading-images-using-javascript-the-right-way-and-without-frameworks_744.html. – Gajus Aug 20 '14 at 21:11
  • The onerror gets called but I can't seem to get the error message from the message parameter. For now I just decrement the counter and do a check to see if it was the last image before calling the callback. Thanks for the help! – Gazillion Aug 21 '14 at 13:56
  • Great answer, but isn't this creating 3 functions on every loop iteration? Maybe predefine a single onload that can be reused for each image? Same for onerror and onabort. – Luiz C. Oct 09 '14 at 13:35
  • This was perfect for me (albeit I was only using one image). I used this to swap a low-quality background-image for a high-quality one. The ability to know when the image had loaded was perfect, and notably absent from the other higher-rated answers! – decates Jan 23 '15 at 12:10
  • @decates This does not sound like a valid use case, though. Have you thought of using progressive loading? See "compression" section of this article, http://en.wikipedia.org/wiki/JPEG – Gajus Jan 25 '15 at 11:59
  • In the case of UI driven interface (as opposed to content), the usual use case is to prevent user from viewing the page before all the necessary images are loaded, e.g. game loading screen. – Gajus Jan 25 '15 at 12:01
  • Why are you wrapping `for` body within an anonymous function? – Greg0ry Oct 07 '15 at 17:22
  • @Greg0ry It is an IIFE used to create a new scope. – Gajus Oct 07 '15 at 17:34
  • Ah, I see. Thought there is maybe other reason. From performance point of view I would think this is not a good practice.. – Greg0ry Oct 07 '15 at 17:36
  • From a performance point of view, there is no measurable difference. You can however use a predefined function if you want (and you should for readability purposes). – Gajus Oct 07 '15 at 19:01
  • Thanks @GajusKuizinas. – Greg0ry Oct 08 '15 at 07:29
35

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.

Dave
  • 4,356
  • 4
  • 37
  • 40
  • 2
    For those that are not interested in messing up the Array.prototype, instead, you can do: `checklist = this.length` And in the onload function: `checklist--` Then: `if (checklist == 0) callback();` – MiniGod Jul 15 '12 at 00:35
  • 3
    Everything would be fine however adding new or removing existing methods to an object you don't own is one of the worst practices in JavaScript. – Rihards Sep 10 '12 at 07:17
  • Nice and quick, but this code will never fire the callback if one of the images is broken or unable to load. – SammyK Oct 30 '12 at 06:38
  • `.attr({ src: this }).load(function() {...})` should be `.load(function() {...}).attr({ src: this })` otherwise you will have caching problems. – Kevin B Mar 27 '13 at 14:31
25

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

$('<img src="img/1.jpg"/>');
rkcell
  • 468
  • 1
  • 6
  • 10
23
$.fn.preload = function (callback) {
  var length = this.length;
  var iterator = 0;

  return this.each(function () {
    var self = this;
    var tmp = new Image();

    if (callback) tmp.onload = function () {
      callback.call(self, 100 * ++iterator / length, iterator === length);
    };

    tmp.src = this.src;
  });
};

The usage is quite simple:

$('img').preload(function(perc, done) {
  console.log(this, perc, done);
});

http://jsfiddle.net/yckart/ACbTK/

yckart
  • 32,460
  • 9
  • 122
  • 129
19

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.
    }  
});
alex
  • 479,566
  • 201
  • 878
  • 984
  • Does this plugin cause images that haven't appeared on the page yet to be loaded, or only attach events to images which were already going to be loaded? – Dave Cameron May 29 '12 at 19:11
  • @DaveCameron It doesn't respect if the images are visible or not. You could easily fork it and make that change - just add `:visible` to the custom selector. – alex May 29 '12 at 23:44
  • This plugin looks very interesting. However, the [jquery documentation](http://api.jquery.com/load-event/) highlights that the `load` event, when applied to images: "doesn't work consistently nor reliably cross-browser". How has the plugin managed to get around that? – EleventyOne Oct 28 '13 at 01:11
  • @EleventyOne Check the source with regard to the custom selector. – alex Oct 28 '13 at 02:18
  • @alex How does this plugin load images that are set in the css on :hover of an element? It does not work for me – Philipp Hofmann Mar 27 '14 at 09:14
  • @muffls The documentation never claims to do this. – alex Mar 27 '14 at 21:21
13

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

example: Html

<img src="someimg.png" class="hide" alt=""/>

Css:

.hide{
display:none;
}

jQuery:

//if want to show img 
$('.hide').show();
//if want to hide
$('.hide').hide();

Preloading images by jquery/javascript is not good cause images takes few milliseconds to load in page + you have milliseconds for the script to be parsed and executed, expecially then if they are big images, so hiding them in hml is better also for performance, cause image is really preloaded without beeing visible at all, until you show that!

itsme
  • 48,972
  • 96
  • 224
  • 345
  • 2
    More info on this approach can be found here: http://perishablepress.com/a-way-to-preload-images-without-javascript-that-is-so-much-better/ – gdelfino Apr 30 '12 at 00:00
  • 3
    But you need to be aware that this technique has a major drawback: your page will not be completely loaded until all images are loaded. Depending on the number of images to preload and their size, this could take some time. Even worse, if the tag does not specify a height and width some browsers might wait until the image is fetched before rendering the rest of the page. –  Feb 01 '13 at 09:18
  • @Alex you anyway need to load the img, you are free to choose if to load them with html and avoid any kind of blinking and half loaded images , or if you want to get more speed going for a not stable solution – itsme Feb 01 '13 at 09:46
  • also i really think creating html tags with javascript is unreadable at all just my 2 cents – itsme Feb 01 '13 at 09:47
  • 1
    I needed a very quick solution for a very complex project and this was it. – Germstorm May 27 '13 at 08:14
  • For UX purposes, I use many hidden images . So, in this case, this solution would not fit ! – Diego Favero Mar 19 '19 at 15:54
13

this jquery imageLoader plugin is just 1.39kb

usage:

$({}).imageLoader({
    images: [src1,src2,src3...],
    allcomplete:function(e,ui){
        //images are ready here
        //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.

alzclarke
  • 1,725
  • 2
  • 17
  • 20
  • 1
    @Ian because the document is already ready by the time the callback is fired. $(document).ready is used to make sure your DOM is loaded. When it comes to the callback, that mean that all images are loaded which means that yoru DOM is loaded so no need for document.ready inside a callback. – Aamir Afridi Mar 06 '13 at 15:09
  • 1
    @AamirAfridi There is no guarantee that the document is ready in the callback...where are you inferring that from? There's nothing on the plugin's page that says the `allcomplete` callback is executed after the DOM is ready. There's a pretty good chance that the images finish loading after the DOM is ready, but there's no reason to assume. I don't know why you think callbacks are magical and are executed after the DOM is ready...can you explain where you're getting that from? Just because the images are loaded doesn't mean the DOM is ready – Ian Mar 06 '13 at 15:47
  • @AamirAfridi And the documentation for the plugin even says: `NB to use this as an image preloader simply put your $(document).ready(function(){}); into your 'allcomplete' event : > simples!` ... it directly recommends what this answer shows. – Ian Mar 06 '13 at 15:49
  • @Ian its always wise to call your plugin(s) inside $(document).ready to avoid all this. – Aamir Afridi Mar 06 '13 at 15:59
  • 5
    @AamirAfridi That makes no sense for this situation. The plugin is a **pre** loader. You want to execute it as soon as possible. And there are plenty of things that don't depend on the DOM that you want to fire as soon as possible, and **then** when the DOM is ready, do something. – Ian Mar 06 '13 at 20:27
  • The link in this answer is dead now. – Qqwy Oct 22 '17 at 20:22
9

A quick, plugin-free way to preload images in jQuery and get a callback function is to create multiple img tags at once and count the responses, e.g.

function preload(files, cb) {
    var len = files.length;
    $(files.map(function(f) {
        return '<img src="'+f+'" />';
    }).join('')).load(function () {
        if(--len===0) {
            cb();
        }
    });
}

preload(["one.jpg", "two.png", "three.png"], function() {
    /* Code here is called once all files are loaded. */
});
​    ​

Note that if you want to support IE7, you'll need to use this slightly less pretty version (Which also works in other browsers):

function preload(files, cb) {
    var len = files.length;
    $($.map(files, function(f) {
        return '<img src="'+f+'" />';
    }).join('')).load(function () {
        if(--len===0) {
            cb();
        }
    });
}
izb
  • 50,101
  • 39
  • 117
  • 168
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.

dmgig
  • 4,400
  • 5
  • 36
  • 47
3
    jQuery.preloadImage=function(src,onSuccess,onError)
    {
        var img = new Image()
        img.src=src;
        var error=false;
        img.onerror=function(){
            error=true;
            if(onError)onError.call(img);
        }
        if(error==false)    
        setTimeout(function(){
            if(img.height>0&&img.width>0){ 
                if(onSuccess)onSuccess.call(img);
                return img;
            }   else {
                setTimeout(arguments.callee,5);
            }   
        },0);
        return img; 
    }

    jQuery.preloadImages=function(arrayOfImages){
        jQuery.each(arrayOfImages,function(){
            jQuery.preloadImage(this);
        })
    }
 // example   
    jQuery.preloadImage(
        'img/someimage.jpg',
        function(){
            /*complete
            this.width!=0 == true
            */
        },
        function(){
            /*error*/
        }
    )
Alex
  • 39
  • 1
  • 7
    Welcome to Stack Overflow! Rather than only post a block of code, please *explain* why this code solves the problem posed. Without an explanation, this is not an answer. – Martijn Pieters Nov 19 '12 at 14:41
3

I use the following code:

$("#myImage").attr("src","img/spinner.gif");

var img = new Image();
$(img).load(function() {
    $("#myImage").attr("src",img.src);
});
img.src = "http://example.com/imageToPreload.jpg";
Cristan
  • 12,083
  • 7
  • 65
  • 69
1

I would use an Manifest file to tell (modern) web browsers to also load all relevant images and cache them. Use Grunt and grunt-manifest to do this automatically and never worry again about preload scripts, cache invalidators, CDN etc.

https://github.com/gunta/grunt-manifest

Christian Landgren
  • 13,127
  • 6
  • 35
  • 31
0
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 :)

Mohammad
  • 21,175
  • 15
  • 55
  • 84
Whisher
  • 31,320
  • 32
  • 120
  • 201
  • Scope `this` inside the callback that is passed to `$.each` is assigned to the value that is being iterated. – Oybek Jul 28 '13 at 08:13
  • ? $(['img1.jpg','img2.jpg','img3.jpg']).each(function (index,value) { console.log(value);//img1.jpg console.log(this);//String { 0="i", 1="m", 2="g", more...} $('').attr('src',this).appendTo('body').css('display','none'); }); – Whisher Jul 29 '13 at 12:32
  • Hm. I guess you are right here. For example `$("div").each(function(i, el){ console.log(el == this);});` generates all `true`s; Iteration over array seems to behave differently. – Oybek Jul 30 '13 at 18:59
0

This works for me even in IE9:

$('<img src="' + imgURL + '"/>').on('load', function(){ doOnLoadStuff(); });
Zymotik
  • 6,412
  • 3
  • 39
  • 48
  • 1
    This will fail eventually due to caching, always bind the load event before setting the src attribute. – Kevin B Mar 27 '13 at 14:27
0

I wanted to do this with a Google Maps API custom overlay. Their sample code simply uses JS to insert IMG elements and the image placeholder box is displayed until the image is loaded. I found an answer here that worked for me : https://stackoverflow.com/a/10863680/2095698 .

$('<img src="'+ imgPaht +'">').load(function() {
$(this).width(some).height(some).appendTo('#some_target');
});

This preloads an image as suggested before, and then uses the handler to append the img object after the img URL is loaded. jQuery's documentation warns that cached images don't work well with this eventing/handler code, but it's working for me in FireFox and Chrome, and I don't have to worry about IE.

Community
  • 1
  • 1
bwinchester
  • 91
  • 1
  • 5
  • This won't work well with cached images as you've found out. the workaround is to bind the load event first, then set the src attribute. – Kevin B Mar 27 '13 at 14:24
0

I usually use this snippet of code on my projects for the loading of the images in a page. You can see the result here https://jsfiddle.net/ftor34ey/

<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.5.1/jquery.min.js"></script>

<img src="https://live.staticflickr.com/65535/50020763321_d61d49e505_k_d.jpg" width="100" />
<img src="https://live.staticflickr.com/65535/50021019427_692a8167e9_k_d.jpg" width="100" />
<img src="https://live.staticflickr.com/65535/50020228418_d730efe386_k_d.jpg" width="100" />
<img src="https://live.staticflickr.com/65535/50020230828_7ef175d07c_k_d.jpg" width="100" />

<div style="background-image: url(https://live.staticflickr.com/65535/50020765826_e8da0aacca_k_d.jpg);"></div>
<style>
    .bg {
        background-image: url("https://live.staticflickr.com/65535/50020765651_af0962c22e_k_d.jpg");
    }
</style>
<div class="bg"></div>

<div id="loadingProgress"></div>

The script save in an array all the src and background-image of the page and load all of them.

You can see/read/show the progress of the loading by the var loadCount.

let backgroundImageArray = [];

function backgroundLoading(i) {

    let loadCount = 0;

    let img = new Image();
    $(img).on('load', function () {

        if (i < backgroundImageArray.length) {

            loadCount = parseInt(((100 / backgroundImageArray.length) * i));
            backgroundLoading(i + 1);

        } else {

            loadCount = 100;
            // do something when the page finished to load all the images
            console.log('loading completed!!!');
            $('#loadingProgress').append('<div>loading completed!!!</div>');

        }

        console.log(loadCount + '%');
        $('#loadingProgress').append('<div>' + loadCount + '%</div>');

    }).attr('src', backgroundImageArray[i - 1]);

}

$(document).ready(function () {

    $('*').each(function () {

        var backgroundImage = $(this).css('background-image');
        var putInArray = false;

        var check = backgroundImage.substr(0, 3);

        if (check == 'url') {

            backgroundImage = backgroundImage.split('url(').join('').split(')').join('');
            backgroundImage = backgroundImage.replace('"', '');
            backgroundImage = backgroundImage.replace('"', '');

            if (backgroundImage.substr(0, 4) == 'http') {
                backgroundImage = backgroundImage;
            }
            putInArray = true;

        } else if ($(this).get(0).tagName == 'IMG') {

            backgroundImage = $(this).attr('src');
            putInArray = true;

        }

        if (putInArray) {
            backgroundImageArray[backgroundImageArray.length] = backgroundImage;
        }

    });

    backgroundLoading(1);

});
Francesco Orsi
  • 1,739
  • 4
  • 16
  • 32
-2

5 lines in coffeescript

array = ['/img/movie1.png','/img/movie2.png','/img/movie3.png']

$(document).ready ->
  for index, image of array
    img[index] = new Image()
    img[index].src = image
Guy Morita
  • 19
  • 5
  • 2
    Can you expand on how solution works to resolve the question in the OP? And possibly comment your code so others can more easily understand it? – Ro Yo Mi Aug 10 '13 at 00:25
-4

For those who know a little bit of actionscript, you can check for flash player, with minimal effort, and make a flash preloader, that you can also export to html5/Javascript/Jquery. To use if the flash player is not detected, check examples on how to do this with the youtube role back to html5 player:) And create your own. I do not have the details, becouse i have not started yet, if i dont forgot, i wil post it later and will try out some standerd Jquery code to mine.

  • This is not a solution. Browser don't support Flash player by default. It can be easily achieve with JavaScript which is the native browser language. – Usman Ahmed May 05 '17 at 17:56
  • I remember the Flash haters from 2012... it was not normal... everywhere i went i was attacked when i even used the word Flash. – Peter Gruppelaar May 06 '17 at 19:08