Skip to content

Instantly share code, notes, and snippets.

@mathiasbynens
Created April 22, 2010 17:11
Show Gist options
  • Star 33 You must be signed in to star a gist
  • Fork 15 You must be signed in to fork a gist
  • Save mathiasbynens/375496 to your computer and use it in GitHub Desktop.
Save mathiasbynens/375496 to your computer and use it in GitHub Desktop.
JavaScript preload() function
/*!
* $.preload() function for jQuery – http://mths.be/preload
* Preload images, CSS and JavaScript files without executing them
* Script by Stoyan Stefanov – http://www.phpied.com/preload-cssjavascript-without-execution/
* Slightly rewritten by Mathias Bynens – http://mathiasbynens.be/
* Note that since this script relies on jQuery, the preloading process will not start until jQuery has finished loading.
*/
jQuery.preload = function(array) {
var length = array.length,
document = window.document,
body = document.body,
isIE = 'fileSize' in document,
object;
while (length--) {
if (isIE) {
new Image().src = array[length];
continue;
}
object = document.createElement('object');
object.data = array[length];
object.width = object.height = 0;
body.appendChild(object);
}
};
// Example:
$(function() {
$.preload([
'http://hang.nodester.com/foo.png?2000',
'http://hang.nodester.com/foo.js?2000',
'http://hang.nodester.com/foo.css?2000'
]);
});
/*!
* JavaScript preload() function – http://mths.be/preload
* Preload images, CSS and JavaScript files without executing them
* Script by Stoyan Stefanov – http://www.phpied.com/preload-cssjavascript-without-execution/
* Slightly rewritten by Mathias Bynens – http://mathiasbynens.be/
*/
function preload(array) {
var length = array.length,
document = window.document,
body = document.body,
isIE = 'fileSize' in document,
object;
while (length--) {
if (isIE) {
new Image().src = array[length];
continue;
}
object = document.createElement('object');
object.data = array[length];
object.width = object.height = 0;
body.appendChild(object);
}
}
// Example:
preload([
'http://hang.nodester.com/foo.png?2000',
'http://hang.nodester.com/foo.js?2000',
'http://hang.nodester.com/foo.css?2000'
]);
@wolthers
Copy link

Hey Mathias. I've been using your version of Stoyan’s script for some time now.

I ran into an issue where the preloaded images takes up space in the body, so you need a method to prevent that. display: none doesnt work as it keeps the browser from downloading it, and visilibility: hidden obviously wont prevent it from taking up space either. Instead, i found adding the .visuallyhidden class (from html5boilerplate) before appending the object, seems to solve all problems.

Here is how I use it:

var Utils = {
    /**
    * JavaScript preload() function
    * Preload images, CSS and JavaScript files without executing them
    * Script by Stoyan Stefanov – http://www.phpied.com/preload-cssjavascript-without-execution/
    * Slightly rewritten by Mathias Bynens – http://mathiasbynens.be/
    * Demo: http://mathiasbynens.be/demo/javascript-preload
    * 
    * - Assumes you have the class .visuallyhidden in your stylesheet - set via a class rather than inline styles to minimize the number of reflows
    * .visuallyhidden { border: 0; clip: rect(0 0 0 0); height: 1px; margin: -1px; overflow: hidden; padding: 0; position: absolute; width: 1px; }
    * .visuallyhidden.focusable:active, .visuallyhidden.focusable:focus { clip: auto; height: auto; margin: 0; overflow: visible; position: static; width: auto; }
    */
    preload: function (arr) {
        var i = arr.length,
            o,
            d = document,
            b = d.body,
            isIE = /*@cc_on!@*/0;
        while (i--) {
            if (isIE) {
                new Image().src = arr[i];
                continue;
            };
            o = d.createElement('object');
            o.data = arr[i];
            o.className += " visuallyhidden";
            b.appendChild(o);
        };
    }
//.... other utils  
}; 

Utils.preload(["image1.jpg", "image2.png", "image3.gif", "script1.js"]);

@mathiasbynens
Copy link
Author

@wolthers Interesting. Are you saying the o.width = o.height = 0; didn’t work for you? It should, especially in an img { display: block; padding: 0; margin: 0; } kind of situation.

@wolthers
Copy link

@mathiasbynens: Indeed it does, it seems right now. That's weird, because I remember rewriting it some time ago because it didnt. Hmm. Go ahead and delete my comments, it only adds confusion.

Copy link

ghost commented Jun 10, 2011

@mathiasbynens Out of curiosity, why doesn't the object fork work in IE?

@mathiasbynens
Copy link
Author

@kitcambridge I’ll defer to Stoyan’s post: http://www.phpied.com/preload-cssjavascript-without-execution/

Note that I basically just rewrote his script a little bit.

Copy link

ghost commented Jun 11, 2011

@mathiasbynens Hmm, I wonder if the browser sniff for IE can be replaced with a weak object inference...maybe isIE = 'fileSize' in document? It doesn't look as though we can feature test for it, but I think a weak inference is slightly more reliable than a sniff.

@mathiasbynens
Copy link
Author

@kitcambridge Great suggestion, thanks!

Copy link

ghost commented Jun 11, 2011

@mathiasbynens Certainly. Looks great!

@wolthers
Copy link

@mathiasbynens It seems that I was right that the objects will take up height in a body { height: 100%; } -scenario (ie. sticky css footer - http://ryanfait.com/sticky-footer/). Will make a demo tonight hopefully. /Michael

@wolthers
Copy link

@mathiasbynens - as promised: http://moredots.dk/etc/preloader-bug-demo/ - issue encountered in newest version of Chrome, Firefox, Safari and Opera. Adding o.style.position = 'absolute' will fix it. /Michael

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment