Jump to content
xisto Community
SystemWisdom

Image Preloader With Progress Bar Status Pure Client-Side JavaScript tested in 4 Browsers

Recommended Posts

I am glad you pointed out the actual problems for me, which makes fixing it one step easier!  I will reply as soon as I figure out a solution.  Hopefully you can test it out again for me on your Mac Safari!! :D

 

145558[/snapback]

Just let me know if you would like me to do any further testing, or provide additional info if needed to make your job easier to find a fix.

 

~ Kai

Share this post


Link to post
Share on other sites

I haven't figured it out yet :(Mac confuses me :PDo you know any Javascript at all? It sounds like a few javascript functions are not being recognized by Safari, amd I am having alot of trouble finding out which ones.. Theoretically, it should work fine, unless Safari browsers haven't followed basic standards for DHTML.. :(Maybe it has to do with it being on a Mac? Did you test it with IE and Firefox from Mac too, or was that on Windows?I am almost at the point of resolving to detect the Safari browser on Mac and just skip preloading altogether, so it doesn't cause problems... :(Well, ima keep looking for an answer, wish me luck! :P

Share this post


Link to post
Share on other sites

Well i will check this out :( ...processing on the client side free's up the server and this script can come quite handy on slower connections :P ...Thanks m8, if it works wrong i will came back to you for help :P Best RegardsNuno

Share this post


Link to post
Share on other sites

Hi

In fact, the problem is that Safari seems to not support self-reference in javascript class.
The two last variables in ImagePreload.prototype.OnLoad are marked as "undefined".

For those who wants to debug in Safari with MacOS, type "defaults write com.apple.Safari IncludeDebugMenu 1" on a terminal and then restart Safari. A "debug" menu will be present on the top of the screen.

I think it's a safari bug, but it should exists a workaround.

Regards,
Riton

I haven't figured it out yet :)
Mac confuses me :)

Do you know any Javascript at all? It sounds like a few javascript functions are not being recognized by Safari, amd I am having alot of trouble finding out which ones.. Theoretically, it should work fine, unless Safari browsers haven't followed basic standards for DHTML.. :(

Maybe it has to do with it being on a Mac? Did you test it with IE and Firefox from Mac too, or was that on Windows?

I am almost at the point of resolving to detect the Safari browser on Mac and just skip preloading altogether, so it doesn't cause problems... :(

Well, ima keep looking for an answer, wish me luck! :)


Share this post


Link to post
Share on other sites

Oh, this is a very interesting code, yet really long :) I'll try to give it a look patiently this weekend and see if I can follow all the steps. Thank you for sharing it.

Share this post


Link to post
Share on other sites

wow great tutorial,I needed this functionality a long time before, but never tried to do it. Thanks for sharing this tutorial.I'd prefer preloading images using CSS rather than Javascript, just for the crooss browser compatability.

Share this post


Link to post
Share on other sites

Greetings wow m8 thats a nice tutorial man

 

thanx

this can sure help me a lot whit some things..

 

i like to see more of your tutorials..

 

 

Thanx SystemWisdom

Share this post


Link to post
Share on other sites

Great and lengthy tutorial there! I managed to read most of it and found it easy to understand and useful for implementing on my own site. Though a condensation of the tutorial or the codes are welcomed. By the way, how would you do it if i want a visitor to view a video or a advertisement of my site while waiting for the site to finish loading?

Share this post


Link to post
Share on other sites

It only works in Internet Explorer?

Image Preloader With Progress Bar Status

 

I used this script for my website, but it only works in the internet explorer... In any other browser it won't work - what could be the problem? I'm using "firebug" for firefox and there are no errors - but only in the ie it comes to the "OnCompletion()"-function.

 

But the script & tutorial is very well work!! congratulations!

 

-reply by daGizmo

Share this post


Link to post
Share on other sites

Rob (systemwisdom)

This is a great tutorial, I'm not a senior developer or anything like that, yet I was able to read the code and understand your instructions. Your code is great, works great and was easy to implement in my own website.

It is highly appreciated that you wanted to provide the script for free to the community and as soon as my coding skills improve, I'll make sure I give something back to the web development community.

I'm a freelance designer/developer just trying to make a name for myself and I appreciate all the help I can get; again many thanks.

Said that, and after I read the replies from everybody, I implemented the code into my own site and it works like a charm.

I tested it with IE7, Mozilla Firefox 2 and 3 (windows and Mac), Safari for (windows and Mac), Opera and even Chrome. It worked just fine in every browser, obviously I know better than most users so I had Javascript enable and made sure I cleared the cache every time I tested it.

I wanted to give my website a professional look, although it's just me doing all the work and this script helped me accomplish a better user experience.

If anybody wants to check it out, the URL is "http://www.fatlizardmedia.com/;

I made a couple changes to the CSS, just to match my color scheme, but other than that it was great to find this script and I'll make sure that I " Render unto Caesar what is Caesar's".

Thanks again.
Juan C Rois

Just a note: The images in my website are PNG 24 with Alpha transparency and IE6 does not render them appropriately, still working on that CSS or Javascript hack.

Share this post


Link to post
Share on other sites

I Haven't tested your code yet, but it is what I need I guess, cause I wanna do a small game attempt, and I would need to use a image lots of times on the same frame instantly, with this sort of pre load I have the possibility right?

Anyway, I can host your image load demo if you wish, just send me a zip of everything.

Share this post


Link to post
Share on other sites

Plain awesome! I really needed this! I'm used to flash and I'm doing preloaders there but I wanted to take a break from flash and do some other things. So I started learning JavaScript. It's really helpful for any of us but I think It's great for the ones who own a freestorage files website. Also well explained with many explanations and hints. Keep the good job.Cheers!

Share this post


Link to post
Share on other sites

Tutorial: Image Preloader with Progress Bar, by Rob J. Secord, B.Sc. (SystemWisdom)

 

 

Description:

A Tutorial for a Client-Side Image Preloader with Dynamic Real-Time Progress Bar Indicator written in JavaScript!

Tested to work with 4 Major Internet Browsers: Firefox, MSIE, Netscape, Opera

 

(Complete sample solution provided at end of tutorial, just put it on your web-server, add your images and go!)

 

 

Intended Audience:

Beginner to Intermediate Web Developers.

 

Although this tutorial will cover some advanced aspects of JavaScript, I will try to explain it all as thoroughly as possible. At the same time, I will keep the functionality basic and leave room for you to expand on it as you see fit.

 

Assumed knowledge:

-- OOP Concepts such as Classes

-- Arrays, Loops

-- JavaScript Basics

-- Working with *.js files

 

 

Background:

Many websites rely on Images for the Graphical User Interface (GUI) of their Web Applications. This is great for visual appeal, but when the site consists of mostly images (both large and small) to make up the entire layout, then your visitors download time ends up taking longer. And as all of us should already know, no one likes to wait too long for a site to load without at least a visual indication of its progress.

On average, people with broadband connections will wait up to 10 seconds for a site to load -- which isn't very much time at all!

 

Another problem while the site is loading for the visitor, is that they see the site slowly take shape, as single images are downloaded individually and fitted into the screen so as to form the layout. It would be much more appealing if the site were to load all at once, images and text loaded and in place all ready to go!

 

The solution? An Image Preloader with Progress Bar Status!

 

Great! But how?

 

 

Theory:

Utilizing the Document Object Model (DOM) of HTML with the power of JavaScript, we can access all of our sites images as Objects, giving us access to the Events fired by the Image Objects.

 

On top of that, when we load an Image in JavaScript via the DOM, we point to the location of the Image via a Uniform Resource Locator (URL) just as we would with regular HTML <IMG> tags. This means that the Image gets loaded into the memory of the visitors computer. Now, when we call for an image in our main page like <img src="img/blah.gif">, the relative Image URL is already loaded, and thus the Image gets displayed immediately.

 

Now as I mentioned before, when we load an Image via JavaScript and the DOM, we have access to the Events of that Image Object, and to name a few of those events we have:

 

OnLoad()

OnError()

OnAbort()

 

Pretty straight-forward really; when the Image is completely loaded the OnLoad() event gets called. If an error occurs while loading the Image the OnError() event gets called. And lastly, if the user (visitor) leaves the page (or closes browser) the OnAbort() event gets called.

 

In this tutorial we will only need to deal with the OnLoad() event, however, the other events could be of great use, and should be simple enough for you to implement on your own after reading this tutorial. (I will leave a basic code structure for the extra events in the sample at the end of this tutorial, but I will not be explaining them in great detail. That could be left open for discussion!)

 

The main purpose of implementing the OnLoad() event is to keep track of our loaded images so we can display a Real-Time Progress Bar to our users. The idea here is to keep a counter of how many images have been loaded, so we know our progress. (Hint: You could also track how many Images fail to load via the OnError() event!)

 

Finally, we have to display that progress on the screen, which can be solved with the use of Span Tags and CSS! In this tutorial I will simply lay out 10 boxes (via Span Tags) each with a Grey BackGround Style, and as the progress increases, I will change the style of each consecutive box to a Blue BackGround, giving a visual appearance of a Progress Bar!

 

I hope you were able to follow along thus far, we are going to tackle the actual code next! Posted Image

 

 

Implementation:

All right! We are going to start on the last section of this tutorial where we actually get to build something! (If you feel daunted by the length of this tutorial at this point, know that the longest section lies yet ahead! Fear not, brave reader!)

 

Now, I am going to take you through 3 stages in building our Image Preloader with Progress Bar:

 

1) Writing the Preloader class in JavaScript -- This is the core of our preloader, and where most of the theory from above takes place;

2) Writing the Progress Bar Page -- This is a simple HTML page used soley to display the Progress Bar to our visitors;

3) Putting it all together -- This is where we will implement the Preloader Class into our Progress Bar Page to make it all work!

 

Due to the 'intertwined' nature of the code, it will be difficult to explain, and you may benefit from reading parts of this section more than once after having read it all. Try to remember any parts that confuse you, and come back to it later, after reading more of the tutorial.

 

 

 

Writing the Preloader class in JavaScript:

We start off by making a new file called 'ipreload.js'. This will be our Image Preloader Class File which will contain a single class declaration. If you have never worked with Classes in JavaScript before, they may seem odd at first. This is due to the fact that JavaScript (ECMAScript) lacks full support for user-defined class types. Posted Image But fret not, my friend! I shall explain them anyway! Posted Image

 

(Note: If you already understand classes in JS, you may safely skip the following quoted section)

 

 

Okay, moving on.. Now that we understand classes in JavaScript, we will begin with our 'ImagePreload' Class. I will first show you the completed class and then I will explain how it works, this way you will have reference to what I am writing about.

 

File = ipreload.js:

<!--  function ImagePreload( p_aImages, p_pfnPercent, p_pfnFinished ) {   	 // Call-back functions	 this.m_pfnPercent = p_pfnPercent;	 this.m_pfnFinished = p_pfnFinished; 	 // Class Member Vars	 this.m_nLoaded = 0;	 this.m_nProcessed = 0;	 this.m_aImages = new Array;	 this.m_nICount = p_aImages.length; 	 // Preload Array of Images	 for( var i = 0; i < p_aImages.length; i++ )		 this.Preload( p_aImages[i] ); }  ImagePreload.prototype.Preload = function( p_oImage ) {   	 var oImage = new Image;	 this.m_aImages.push( oImage ); 	 oImage.onload = ImagePreload.prototype.OnLoad; 	 oImage.oImagePreload = this;  // Give the Image Object a Reference to our Class..	 oImage.bLoaded = false;	   // Custom value added to track state	 oImage.source = p_oImage;	 // Original Source Path to Image (for later use)	 oImage.src = p_oImage;		// Image Object Source Path  }  ImagePreload.prototype.OnComplete = function() {   	 this.m_nProcessed++;	 if ( this.m_nProcessed == this.m_nICount )		 this.m_pfnFinished();	 else		 this.m_pfnPercent( Math.round( (this.m_nProcessed / this.m_nICount) * 10 ) ); }  ImagePreload.prototype.OnLoad = function() {   	 // 'this' pointer points to oImage Object because this function was previously assigned	 // as an event-handler for the oImage Object.	 this.bLoaded = true;	 this.oImagePreload.m_nLoaded++;	// Access our Class with the Reference assigned previously..	 this.oImagePreload.OnComplete(); }  //-->

Okay, we have a class called 'ImagePreload' whose constuctor takes 3 parameters, namely p_aImages, p_pfnPercent and p_pfnFinished respectively.

The first parameter 'p_aImages' is an Array of Strings which holds the URL of all of the images we want to Preload. We will build this array outside of this class later on, and pass it into the class when we instantiate an object of the class.

The second and third parameters are actually Functions (or more precisely, Function Pointers) that we want our class to have access to without being part of the class itself. We will deal more with these later.

 

Now looking into the Constructor function for our class we will see that the last two parameters are being assigned to Member Variables of the class, so that they are stored locally and are available for the class to call as functions later on. They are commented as "Call-Back functions", and that is exactly what they are: They "Call-Back" to the code that "Called" our Class' Constructor/Member Functions. More over, they can be considered Events that are raised by our class. I will elaborate on this further later in this tutorial. Moving on..

 

Next you will see some more Member Variables being declared within the class, namely: m_nLoaded, m_nProcessed, m_aImages and m_nICount. I will try to explain them each briefly, yet adequately each in a single paragraph of their own;

 

Since our class will keep a counter for all of the Images it loads, we will need a Member Variable to hold that counter, starting at 0. The 'm_nLoaded' Member Variable serves this purpose. After each successfully loaded image, 'm_nLoaded' will be incremented by 1.

 

Our class will also keep a counter for the number of Processed Images (meaning the images that our Progress Bar has accounted for) to calculate the Overall Progress. The 'm_nProcessed' Member Variable serves this purpose. This should be unaffected by Image Load Failures from the OnError() events (Be sure to note that if you plan to add error handling to this class).

 

Our class will also be storing the Image Objects in Memory on the visitors machine, so that they are considered "Preloaded", and we will do this by creating an Array, and adding the Image Objects to the Array as the images are loaded. The 'm_aImages' Member Variable serves this purpose. Note that this Member variable starts with 'm_' unlike the parameter with the same name, which starts with 'p_'.

 

Finally, our class will need to know the total number of images it is preloading in order to compute a progress, and yes, the 'm_nICount' Member Variable serves this purpose! We can get this value from the Arrays 'length' property, which returns the number of elements in the array.

 

Okay, so that should explain most of the Constructor function to you, and now we will look at the last part of the code in the constructor function.. Hopefully, you've kept up with me and the reference code above, if not here is the part I am refering to next:

// Preload Array of Images	 for( var i = 0; i < p_aImages.length; i++ )		 this.Preload( p_aImages[i] );

This is a basic FOR loop which we will use to walk through the Array of Image URLs that were passed into the function as the First Parameter. We will then pass each individual URL string to our class' Preload() Member Function which handles the actual "Preloading" of each Image Object.

As you can see by now, as soon as you Instantiate the ImagePreload Object passing it the Array of Image URLs, the preload process will start immediately, and within seconds (hopefully) all of your Images will be preloaded!

 

But wait! What about the progress bar?!

Since the ImagePreload class will be taking care of loading all of those images, how will the Progress Bar know what's going on?

 

This is solved by those two "Call-Back" functions I mentioned earlier. Since the Progress Bar itself will be completely seperate code with a seperate responsibility, it will have two functions of its own. One function will update the Progress Bar Display, and the other function will redirect to the main page of your site when the preloading is done!

 

Now, as I mentioned earlier, the two "Call-Back" functions were assigned to Member Variables which means that any function in our class can now call either of those two functions whenever it needs to. Basically, we will use them as Events, so that everytime an image is loaded, the progress is calculated and the Event (Call-Back Function) is called, sending back the current progress! Now since those functions actually belong to (and are coded in) the Progress Bar, then they will get called and Instantly Update the Progress or Redirect the Page Accordingly!

 

Hopefully that made sense to you, either way, I shall explain it in more detail.

In reference to the code above, we should now be looking at the Preload() function declared as:

ImagePreload.prototype.Preload = function( p_oImage )

Recall that this function is executed in the FOR loop in the Constructor of our Class, and is being passed a URL string of the Image to Preload. Looking into the function we notice the first two statements, the first line just instantiates an Image Object (which is part of JavaScript) and the second line adds that Image Object into our Array of Image Objects which we had declared earlier in the Constructor. Memory space is now reserved for this image on the visitors computer!

 

Next, we see a see a statement dealing with the OnLoad() event of the Image object:

oImage.onload = ImagePreload.prototype.OnLoad;

We are basically telling the Image Object to Call a Member Function in our class when the Image is loaded, and our Member Function will be responsible for tracking the progress.

But there is one tricky thing to note about this assignment; the 'ImagePreload.prototype.OnLoad' function now "belongs" to the Image Object, even though the function is implemented in our class. The important point is that the 'this' keyword within our 'ImagePreload.prototype.OnLoad' Member Function will not point to our 'ImagePreload' Object Instance, but rather the Image Object Instance. (Crude Analogy: this is not this anymore, it is that! Posted Image)

This may seem very confusing at first, but don't give up! It makes sense! Besides, you don't have to understand it, just know that it works and how to use it!

 

Now if you didn't understand what I just wrote, then the next statement won't make much sense to you:

oImage.oImagePreload = this;  // Give the Image Object a Reference to our Class..

Basically, we want the Image Object to have access to our Class. This is used to access the Call-Back functions in our class from within the OnLoad() function which now belongs to the Image Object. Make sense? I hope so, I don't know how else to explain it! Posted Image But don't fret my friend, read further! Maybe it will clear up for you later!)

 

The next few statements are much simpler:

oImage.bLoaded = false;	   // Custom value added to track state	 oImage.source = p_oImage;	 // Original Source Path to Image (for later use)	 oImage.src = p_oImage;		// Image Object Source Path

The first is just a simple boolean flag to indicate whether the Image Object has been loaded or not, which is set to False by default.

The next two lines are pretty much the same, except that the first one is a custom variable and the second one is actually an Image Object Property 'src', much like in HTML <IMG> Tags. When you assign a a URL to this property it will be interpreted immediately and the actual image will be loaded into the Memory space we had reserved earlier! This is the load process internally, and when then image is done loading the OnLoad() event gets fired calling our OnLoad() Member Function.

The custom variable 'source' is used for referencing the original path & filename of the image (if you should need to) whenever you need to.

 

And that is the Preload() function!! Hopefully, you now understand how the actual Preload process works!

 

We will now move on to the final 2 Member Functions: OnLoad and OnComplete..

 

ImagePreload.prototype.OnLoad = function() {   	 // 'this' pointer points to oImage Object because this function was previously assigned	 // as an event-handler for the oImage Object.	 this.bLoaded = true;	 this.oImagePreload.m_nLoaded++;	// Access our Class with the Reference assigned previously..	 this.oImagePreload.OnComplete(); }

Now, since the OnLoad() function belongs to the Image Object, we can directly manipulate the variables we gave it earlier, namely the 'bLoaded' boolean flag. We will set this to true, to indicate that this image object was loaded successfully.

We also need to increment the counter holding the total number of Loaded Images thus far, which is a Member Variable that belongs to the ImagePreload class, and this function doesn't! So, we access the reference we stored earlier as a custom variable in the Image Object. We can now use that reference object to access anything in our ImagePreload class, which the next two statements do; the first of which simple increases the counter, and the second calls our final Member Function 'OnComplete'.

 

ImagePreload.prototype.OnComplete = function() {   	 this.m_nProcessed++;	 if ( this.m_nProcessed == this.m_nICount )		 this.m_pfnFinished();	 else		 this.m_pfnPercent( Math.round( (this.m_nProcessed / this.m_nICount) * 10 ) ); }

This function is pretty simple, it belongs to our ImagePreload class and simply increments the counter of Processed Images. (Note: If the # of Processed Images is not equal to the # of loaded images, then some of your imges fail to load. But the progress will still compute correctly!)

 

Next it checks to see if it has processed all the required images, and if so it raises the "Finished" event, which tells the Progress Bar code to redirect to the main page. However, if it is not done loading all of the required images, it will raise the "Percent" event, which tells the Progress Bar to update the display according to the Percent Complete!

(The Percentage is rounded to a single digit number from 1-10, but this could easily be changed to suit your needs).

 

Whew! Take a break! Your done Stage 1 of the Implementation Section! It's pretty much downhill from here! Posted Image

 

 

Writing the Progress Bar Page:

I am going to keep this part of the tutorial a simple as possible, since it only deals with basic HTML tags, and some simple CSS styles for appearance. This is going to be the GUI of the Progress Bar, and most of you will probably change the appearance of it anyway.

 

Basically, you just need an empty webpage (preferably no images, otherwise, what's the point of the Preloader?)

So it could look something like this (keeping it simple):

 

File = index.html:

<html> <head> <style type="text/css"><!--  .OuterBorder {  border:1px solid #426394;	padding: 2px 5px 2px 5px; } .FullDot {  border:1px solid #426394;	background-color:#DAE1EB;	cursor:default; } .EmptyDot {  border:1px solid #426394;	background-color:#F3F6FA;	cursor:default; } //--></style> </head> <body>   <center>  <table cellpadding="0" cellspacing="0" border="0" class="OuterBorder">   <tr>	<td>	   <span id="sDot1" class="EmptyDot">  </span> 	   <span id="sDot2" class="EmptyDot">  </span> 	   <span id="sDot3" class="EmptyDot">  </span> 	   <span id="sDot4" class="EmptyDot">  </span> 	   <span id="sDot5" class="EmptyDot">  </span> 	   <span id="sDot6" class="EmptyDot">  </span> 	   <span id="sDot7" class="EmptyDot">  </span> 	   <span id="sDot8" class="EmptyDot">  </span> 	   <span id="sDot9" class="EmptyDot">  </span> 	   <span id="sDot10" class="EmptyDot">  </span>	</td>   </tr>  </table>  </center>  </body> </html>

You'll notice it is just 10 span tags within a bordered table, each span tag representing an 'EmptyDot'. As the progress increases, the 'EmptyDots' will become 'FullDots'.

 

Well, nothing special there, just some regular HTML/CSS stuff.. So, we move on, to the Final Stage!

 

 

Putting it all together:

This stage shouldn't be too tricky either.. First we will have to include or ImagePreload class file into our HTML page, then we will write our 2 functions that will respond to the events raised by our ImagePreload class, as well as a third function to start the whole Loading process rolling! Also, we will add an extra link on the page, that will give the visitor the option to "Skip Preload" and go straight to the main page..

 

First, including the Preloader, which most of you I assume will be familiar with. Simple JS file including:

<script type="text/javascript" language="JavaScript" src="ipreload.js"></script>

Now, we want to create 3 more JavaScript functions inside the <HEAD> tag of the web page, as mentioned earlier. I will first show you the completed HTML file, and then like before, I will explain it all to you, with the code as reference:

 

File = index.html:

<html> <head> <style type="text/css"><!--  .OuterBorder {  border:1px solid #426394;	padding: 2px 5px 2px 5px; } .FullDot {  border:1px solid #426394;	background-color:#DAE1EB;	cursor:default; } .EmptyDot {  border:1px solid #426394;	background-color:#F3F6FA;	cursor:default; } //--></style>  <script type="text/javascript" language="JavaScript" src="ipreload.js"></script>  <script type="text/javascript" language="JavaScript"><!--  var g_iStep = 0;  function OnImgUpdate( iProgress ) {   	 if( (iProgress >= 1) && (iProgress <= 10) && (iProgress > g_iStep) )	 {   		 g_iStep++;		 var oSpan = document.getElementById( "sDot" + iProgress + "" );		 oSpan.className = 'FullDot';	 } }  function OnCompletion() {   	 document.location.replace('main.html'); }  function StartPreload() {	 var szImages = new Array( "image1.gif", "image2.jpg", "image3.png", "etc..." ); 	 // Execute Image Preloader	 var oPreload = new ImagePreload( szImages, OnImgUpdate, OnCompletion ); }  --></script>  </head> <body onload="StartPreload()">   <center>  <table cellpadding="0" cellspacing="0" border="0" class="OuterBorder">   <tr>	<td>	   <span id="sDot1" class="EmptyDot">  </span> 	   <span id="sDot2" class="EmptyDot">  </span> 	   <span id="sDot3" class="EmptyDot">  </span> 	   <span id="sDot4" class="EmptyDot">  </span> 	   <span id="sDot5" class="EmptyDot">  </span> 	   <span id="sDot6" class="EmptyDot">  </span> 	   <span id="sDot7" class="EmptyDot">  </span> 	   <span id="sDot8" class="EmptyDot">  </span> 	   <span id="sDot9" class="EmptyDot">  </span> 	   <span id="sDot10" class="EmptyDot">  </span>	</td>   </tr>  </table>  </center>  </body> </html>

Now, the first thing you'll notice, is that there is not much left to do! Yay! I'm exhausted from typing! Okay, going back on track now...

 

You could seperate the CSS and put it in an external *.css file if you prefer, but I kept this tutorial simple, with the use of only 2 files (plus the rest of your website).

 

The first thing to note in the newely added JavaScript code block is:

var g_iStep = 0;

This is a global variable that needs to maintain its value, hence it is declared outside of any specific code block. The reason for this variable is simple; The Progress Bar display in this tutorial only has 10 steps, but you could have 50+/- images. Since the Update Event gets called for every loaded image, then it is unnesseccary to Update the progress bar with every image, instead we track when the Percent value changes, store the new value in the 'g_iStep' variable and Update the display only if the 'g_iStep' variable has increased!

 

This all takes place in the 'OnImgUpdate' function:

function OnImgUpdate( iProgress ) {   	 if( (iProgress >= 1) && (iProgress <= 10) && (iProgress > g_iStep) )	 {   		 g_iStep++;		 var oSpan = document.getElementById( "sDot" + iProgress + "" );		 oSpan.className = 'FullDot';	 } }

Should be pretty straight-forward from what I wrote above. Worth noting though, is the 'oSpan' variable, which refers to one of the HTML <SPAN> tags in the DOM that make up the Progress Bar Display. We can get access to this Span Tag as an Object via the 'document.getElementById()' function which is part of JavaScript. All we need to do, is tell the function the ID of the Span Tag, which we have named successively ranging from "sDot1" to "sDot10". Each ID corresponds to a Progress Interval. Now that we have access to the Span Tag Object, we can change its Style via the 'ClassName' property, which we then change to 'FullDot' so as to indicate a Full Dot, and Progress on the Progress Bar!

 

Well, that takes care of the Progress Bar actually moving! Now we have to Redirect to the Main page of your site once it is complete. Our ImagePreload class will take care of raising the Event when all of the images are loaded, we just need to do something now when that event occurs.

 

This will happen in our 'OnCompletion()' function:

function OnCompletion() {   	 document.location.replace('main.html'); }

Pretty simple really, if you understand the Basics of Javascript. We just Redirect to the Main page of your site (assuming the page is called 'main.html', if not point it to your page). Also, the replace() function has the added benefit of removing the preloader from the history, so people don't click there Back button and go to a Preloader page!

 

 

And finally, where my tutorial draws near to its conclusion, we put it all together in one Simple function:

function StartPreload() {	 var szImages = new Array( "image1.gif", "image2.jpg", "image3.png", "etc..." ); 	 // Execute Image Preloader	 var oPreload = new ImagePreload( szImages, OnImgUpdate, OnCompletion ); }

Now the first thing you will notice, is the Array of Image URLs, these are "Relative" URLs and should point to the actual image files on your webserver that you wish to preload. This script will not work "As Is" unless you point to Your image files in the Array.

 

How ever you build that Array of images is up to you, I personally use PHP to recurse through my /img/ directory making a list of all the Image path/filenames it finds, and then outputs that list into the Preloader Pages Image URL Array above. That would be a tutorial of it's own, so I will save going into detail about that for another day!

 

Next, is the MAin line of execution for our Preloader script.

var oPreload = new ImagePreload( szImages, OnImgUpdate, OnCompletion );

In this one line is where we Instantiate a new 'ImagePreload' Object, passing to its Constructor 3 parameters: the Array of Image URLs, the 'Update' Event Function Pointer and the 'Finished' Event Function Pointer which starts the whole Preloading process in motion!

 

The 'StartPreload' function should be called as soon as the Preload Page loads, so we will call it in the onload event handler of the Body Tag:

<body onload="StartPreload()">

And there you have it! An Image Preloader with Progress Bar Status in JavaScript!

 

So, as the End-Result, we have the 2 completed Files (with the extra stuff I mentioned left in):

 

File = ipreload.js:

<!--  function ImagePreload( p_aImages, p_pfnPercent, p_pfnFinished ) {   // Call-back routines	 this.m_pfnPercent = p_pfnPercent;	 this.m_pfnFinished = p_pfnFinished; 	 // Class Member Vars	 this.m_nLoaded = 0;	 this.m_nProcessed = 0;	 this.m_aImages = new Array;	 this.m_nICount = p_aImages.length; 	 // Preload Array of Images	 for( var i = 0; i < p_aImages.length; i++ )		 this.Preload( p_aImages[i] ); }  ImagePreload.prototype.Preload = function( p_oImage ) {   var oImage = new Image;	 this.m_aImages.push( oImage ); 	 oImage.onload = ImagePreload.prototype.OnLoad;	 oImage.onerror = ImagePreload.prototype.OnError;	 oImage.onabort = ImagePreload.prototype.OnAbort; 	 oImage.oImagePreload = this;	 oImage.bLoaded = false;	 oImage.source = p_oImage;	 oImage.src = p_oImage; }  ImagePreload.prototype.OnComplete = function() {   this.m_nProcessed++;	 if ( this.m_nProcessed == this.m_nICount )		 this.m_pfnFinished();	 else		 this.m_pfnPercent( Math.round( (this.m_nProcessed / this.m_nICount) * 10 ) ); }  ImagePreload.prototype.OnLoad = function() {   // 'this' pointer points to oImage Object	 this.bLoaded = true;	 this.oImagePreload.m_nLoaded++;	 this.oImagePreload.OnComplete(); }  ImagePreload.prototype.OnError = function() {   // 'this' pointer points to oImage Object	 this.bError = true;	 this.oImagePreload.OnComplete(); }  ImagePreload.prototype.OnAbort = function() {   // 'this' pointer points to oImage Object	 this.bAbort = true;	 this.oImagePreload.OnComplete(); }  //-->

File = index.html:

<html> <head> <style type="text/css"><!--  .OuterBorder {  border:1px solid #426394;	padding: 2px 5px 2px 5px; } .FullDot {  border:1px solid #426394;	background-color:#DAE1EB;	cursor:default; } .EmptyDot {  border:1px solid #426394;	background-color:#F3F6FA;	cursor:default; } //--></style>  <script type="text/javascript" language="JavaScript" src="ipreload.js"></script>  <script type="text/javascript" language="JavaScript"><!--  var g_iStep = 0;  function OnImgUpdate( iProgress ) {   	 if( (iProgress >= 1) && (iProgress <= 10) && (iProgress > g_iStep) )	 {   		 g_iStep++;		 var oSpan = document.getElementById( "sDot" + iProgress + "" );		 oSpan.className = 'FullDot';	 } }  function OnCompletion() {   	 document.location.replace('main.html'); }  function StartPreload() {	 var szImages = new Array( "image1.gif", "image2.jpg", "image3.png", "etc..." ); 	 // Execute Image Preloader	 var oPreload = new ImagePreload( szImages, OnImgUpdate, OnCompletion ); }  --></script>  </head> <body onload="StartPreload()">   <center>  <table cellpadding="0" cellspacing="0" border="0" class="OuterBorder">   <tr>	<td>	   <span id="sDot1" class="EmptyDot">  </span> 	   <span id="sDot2" class="EmptyDot">  </span> 	   <span id="sDot3" class="EmptyDot">  </span> 	   <span id="sDot4" class="EmptyDot">  </span> 	   <span id="sDot5" class="EmptyDot">  </span> 	   <span id="sDot6" class="EmptyDot">  </span> 	   <span id="sDot7" class="EmptyDot">  </span> 	   <span id="sDot8" class="EmptyDot">  </span> 	   <span id="sDot9" class="EmptyDot">  </span> 	   <span id="sDot10" class="EmptyDot">  </span>	</td>   </tr>  </table>  </center>  </body> </html>

Conclusion:

 

Well, I hope that you have learned something from this tutorial, and maybe even use such a preloader in your web sites!

 

Also note, that this Preloader won't work well with less than 10 images, but in that case you don't need a preloader like this one!

 

Please feel free to comment on this tutorial, if you noticed anything wrong or out of place in this tutorial, please don't hesitate to mention it!

I am interested in all feedback really, I'm curious about what you think of my writing, tutorial, methods used, code, etc.. Thanks!

 

I would have a working example to show, but my web host went down a while back. Sorry!

 

Read part 2 of this tutorial entitled "Extending the Image Preloader with PHP4"

 

Notice from BuffaloHELP:
Edited per request.
a very long tutorial...

i wonder how much time you need to write this tutorial...?

anyways, great tutorial! you explained everything very clear

i'm sure this will be very easy for people to understand it... :D

Share this post


Link to post
Share on other sites
How to use that?Image Preloader With Progress Bar Status

Hi,

sorry friends, I read the above cursory, and I'm Astigmatic you know /txtmngr/images/smileys/smiley1.Gif

Could someone tell me, How we can use that?!

I mean, after preloading images, when we are here:

<img name='something' src= ###   >

what should we write stead of ### ?

-reply by Armin

Share this post


Link to post
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now

×
×
  • Create New...

Important Information

Terms of Use | Privacy Policy | Guidelines | We have placed cookies on your device to help make this website better. You can adjust your cookie settings, otherwise we'll assume you're okay to continue.