O'Reilly

MooTools Image Preloading with Progress Bar

By on  

The idea of image preloading has been around since the dawn of the internet. When we didn't have all the fancy stuff we use now, we were forced to use ugly mouseover images to show dynamism. I don't think you were declared an official programmer until you had seen Macromedia Dreamweaver's mouseover function. MooTools image preloading requires very little code -- let me show you how it's done.

If you haven't experienced the dwProgressBar class for MooTools, please read this article. I wont be featuring an explanation of that code in this article.

The XHTML

<div id="progress-bar"></div>
<div id="images-holder"></div>

I've created two DIVs which will act as "holders" for the progress bar and the images.

The MooTools JavaScript

window.addEvent('domready', function() {
	/* progress bar */
	var progressBar = new dwProgressBar({
		container: $('progress-bar'),
		startPercentage: 0,
		speed:750,
		boxID: 'box',
		percentageID: 'perc',
		displayID: 'text',
		displayText: true
	});
	
	/* preloading */
	var images = ['1.jpg','2.jpg','3.jpg','4.jpg','5.jpg','6.jpg','7.jpg','8.jpg','9.jpg','10.jpg'];
	var loader = new Asset.images(images, {
		onProgress: function(counter,index) {
			progressBar.set((counter + 1) * (100 / images.length));
		},
		onComplete: function() {
			images.each(function(im) {
				new Element('img',{ src:im, width:200, style:'width:200px;margin:20px 20px 20px 0;' }).inject($('images-holder'));
			});
		}
	});
});

The code to preload images is shockingly short. We provide Asset.images() an array of images (string paths to the images on the server). On every image load, we adjust the progress bar. Finally, once all images have loaded, we inject them into the image holding DIV.

Be sure to view the example featuring the ever-beautiful Christina Ricci!

O'Reilly Velocity Conference
Save 20% with discount code AFF20

Recent Features

  • Creating Scrolling Parallax Effects with CSS

    Introduction For quite a long time now websites with the so called "parallax" effect have been really popular. In case you have not heard of this effect, it basically includes different layers of images that are moving in different directions or with different speed. This leads to a...

  • fetch API

    One of the worst kept secrets about AJAX on the web is that the underlying API for it, XMLHttpRequest, wasn't really made for what we've been using it for.  We've done well to create elegant APIs around XHR but we know we can do better.  Our effort to...

Incredible Demos

  • MooTools History Plugin

    One of the reasons I love AJAX technology so much is because it allows us to avoid unnecessary page loads.  Why download the header, footer, and other static data multiple times if that specific data never changes?  It's a waste of time, processing, and bandwidth.  Unfortunately,...

  • Digg-Style Dynamic Share Widget Using MooTools

    I've always seen Digg as a very progressive website. Digg uses experimental, ajaxified methods for comments and mission-critical functions. One nice touch Digg has added to their website is their hover share widget. Here's how to implement that functionality on your site...

Discussion

  1. Haha, this girl are great, :)
    Good tip David.

  2. david walsh, as you can see on this screenshot, using ie7 the pics are enlarged. pd. maybe is a mootools problem?

    http://img247.imageshack.us/img247/1838/oo956e2tmpll4.jpg

  3. Didn’t I request an ass shot? HA.

  4. I’ve seen image preloading done before with only two images. The stripped bar would be a small repeatable image and then there would be a solid bar. (I guess it can be done with one.) Then the two divs would be right next to each and then one would grow and the other would shrink. Until the solid one would have a width of 0.

  5. @Josep: IE7 must be acting odd with the images. The images are actually huge so that the progress bar wouldn’t be skipped right away. IE used to constrain those proportions. Apparently not anymore.

    @Chris: How could I forget?

  6. elvis 2k

    It’d be cool to have the progress bar discreetly disappear when it reached 100%.

  7. But… how do you preload the preload images?

  8. @Sean: The preloading code starts on line 15 with Asset.images();

  9. It was a joke… but… what if the preload images are not loaded (for some unknown reason), does it still look ok without them?

  10. @SeanJA: There’s only one way to find out! Try it.

  11. Dan

    Hey Dave,
    is there a convenient way to inject the values of the array

    var images()

    vith Ajax?

    Cheers Dan

  12. @Dan: Good question. Here’s one possible hack:

    Use ajax to build a string that looks like: ‘1.jpg’, ‘2.jpg’. Split that string using the .split() function.

    Now you have your array.

  13. Deto15

    That’s an awesome usage of mootools ^^
    I had a problem with website preloader because I have tons of images as css backgrounds but Firefox 2 run body.onload event without downloading those… And now not only I can fix it, but have it with percentage bar :3

    Big thanks for help ^^

  14. david, great use of mootools and love your blog. I’ve played with your example, and I’ve noticed that onComplete doesn’t work properly in firefox. The preloaded image seems to load twice in FF, however it successful in IE/Opera/Chrome/Safari. Have you come across this issue before? Would love to hear a workaround if possible! TIA!

  15. Birke

    Very cool David!

    Is it possible to hide the progress bar after the images are fully loaded? How can this be done?

  16. @Birke: Definitely — you’d use the “loader” variable’s onComplete function to place the “hide” code.

  17. Birke

    Thank you very much for your fast reply. This was my first idea to use this function. I tried to do this with fx.slide from mootools demo page, but had no luck until yet to get it to work.

    var myFx = new Fx.Slide('images-holder', {
    duration: 'long',
    transition: Fx.Transitions.Bounce.easeOut
    
    
    });
    
    onComplete: function() {  
                images.each(function(im) {  
                    new Element('img',{ src:im, width:200, style:'width:200px;margin:20px 20px 20px 0;' }).inject($('images-holder'));  
                });  
                fx.hide();
      } 
    
  18. Jonathan

    How can i hide the progress bar after loading the images?

  19. Manolis

    Hi,

    Would it possible to use it as a preloader for other objects (like swf) , and how?

    Thanks in advance.

  20. Guillem

    Is there a way to retrieve images addresses (url) already placed into a div, ask mootools not to load them the usual way, store them into an array and then, use your code?

    Thanks

  21. Gui

    what if you want to show the preloader for each image, when loaded that one, show preloader for the next and so on

  22. Gui: What value does showing the progress of each image have? Showing the progress as a whole is more important. In any case, I suppose you could use multiple progress bars.

  23. F3

    hi there David –

    this is really great.

    I’m having one issue and I wonder if you’ve run into it before and/or have any advice. in Firefox and Safari, all is wonderful. In Windows IE 6, my code is never hitting the onComplete block – it stops at 96%.

    I added an alert to the onProgress block that prints this debug info out:

    “finished ” + index + ” out of ” + images.length + ” images”

    in Firefox, images.length is 26, but in IE 6, images.length is 27, so this may be causing the problem.

    this seems like more of a problem with Asset.images than dwProgressBar, but I’d be surprised if I were the only person seeing this behavior.

    have you seen or heard anything about this? your advice is appreciated!

  24. F3

    well, I fixed my own problem:

    http://jszen.blogspot.com/2004/07/array-length-headaches.html

    I had an extra comma following the last image in my image array.

    thanks anyway! :)

  25. Sania

    hey could u plz tell me how to show some text with that 100% i mean that variable goes from 0 to 100 % so i want to display this text with it “loading images” of course without quotes.

  26. Hi, david, one question,, if i want use this script for load data from database mysql usign php, and show Preloader while load data ? How do this.

  27. How can i remove the progress bar after it load the images?

  28. Thomas

    Is there anyway to make the bar disappear when it reaches 100% ?

  29. Harrison

    how could i set this to load HTML content instead of images or just have it forward to an HTML page. sorry, kinda a JS noob, techin myself

  30. Awesome sauce David!
    Anyway, ..just a pointer for anybody who needed the let’s-get-the-progress-bar-disappear after the images done loaded.

    Using the eggsact hint from David,
    * use the “loader” variable’s onComplete function to place the “hide” code.*
    ..in here i use the simple fade to 0.

    onComplete: function() {
      images.each(function(im) {
        new Element('img',{ src:im, width:200, style:'width:200px;margin:20px 20px 20px 0;' }).inject($('images-holder'));
      }), // change this part into [,] so we can continue to our "hide" code
      $('progress-bar').fade(0); // let's fade it to 0 opacity, shall we..
    }
    

    Hope it helps.

  31. It’s very good.
    I like this.
    Thanks for share.
    And I wrote something to introduce this project for my readers.
    You can find the post about this in my website.
    If something is wrong,pls figure it out.thanks.

  32. Ariel

    Hi David, is there an onProgress callback for the Asset.javascript method? Thanks for this!

  33. Ariel

    After taking a look at the code, onProgress is called only after an image has been successfully loaded. This doesn’t seem to be possible to be achieved with JS files. hmm…

  34. wow….this works great…:) Well i was looking for the preloaded with progress… thanks I am trying this right now…If I have any issues i will let you know.. :)

  35. is it anyway after 100% progress bar disappear and show’s message

  36. peter

    i receive this error msg:
    Error: $(this.options.percentageID) is null
    Sourcefile: xxx/js/dwProgressBar.js
    Row: 59

    How to fix this ?

  37. Domenico de Giulii

    Hi David,
    great script, but it doesn’t work with Internet Explorer 9.
    Does it contain any deprecated (according to Microsoft) javascript method?

    Thank you in advance!

  38. I admit, I have not been on this webpage in a long time however it was another joy to see It is such an important topic and ignored by so many, even professionals. I thank you to help making people more aware of possible issues.Great stuff as usual.

  39. Hi David,

    i found the error it was in this code

    onProgress: function(counter,index) {
        progressBar.set((counter + 1) * (100 / images.length));
    },
    
    
    i had to cancel the + 1 after counter. i don't know why but it went up to 120%, know it goes only to 100%.
    
    Thank you agoin for the script.

Wrap your code in <pre class="{language}"></pre> tags, link to a GitHub gist, JSFiddle fiddle, or CodePen pen to embed!

Recently on David Walsh Blog

  • Prevent Chrome from Translating a Page

    A while back I shared my favorite Google Chrome extension:  Google Art Project.  I've enjoyed seeing beautiful art when I open a new tab -- it's brought genuine happiness to my day, however small that happiness may be.  About a week ago, however, the art presented had...

  • Create Any Type Of Website With These Multi-Purpose Themes

    We have selected what we believe are the very best multipurpose WordPress themes on the market today. Our list contains a number of best sellers, several newcomers that are proving to be highly popular, and a few themes that are ideal for creating the types of...

  • An Introduction to Static Site Generators

    Static site generators seem to have been becoming more and more popular recently, but they’re not one of those ephemeral novelty things that grow in popularity as quickly as they fall into oblivion shortly after. For over a decade, many different projects — 394 of...

  • Automated Tests for Visual Responsive Layouts

    Today it's all about testing. In 2015, many developers knows about TDD and I personally think that testing is one of the key for quality products. But what about testing in a Front-end environment? How do you guys write your tests for a responsive page or...

  • Getting Dicey With Flexbox

    What if you could build complex CSS layouts in minutes? Flexbox is a new CSS layout spec that makes it easy to construct dynamic layouts. With flexbox, vertical centering, same-height columns, reordering, and direction agnosticism are a piece of cake. There's a popular myth floating around that...