PDA

View Full Version : JavaScript image preloader


MinatureCookie
July 7th, 2007, 17:51
Hey guys, so I've decided I want a nice little image preloader on my site, but I have no idea how to make one.
I got a script off that 'Dynamic Drive'? Site... Or something like that, but I'd much rather actually write my own script and understand it than use someone elses, besides theirs doesn't work in IE. The codec is:-

// Progressbar - Version 2.0
// Author: Brian Gosselin of http://scriptasylum.com
// Featured on Dynamic Drive (http://www.dynamicdrive.com)
// PUT THE NAMES OF ALL YOUR IMAGES THAT NEED TO BE "CACHED" IN THE "imagenames" ARRAY.
// DONT FORGET THE COMMA BETWEEN EACH ENTRY, OR THE TICK MARKS AROUND EACH NAME.
// WHEN ALL THE IMAGES ARE DONE LOADING, THE "imagesdone" VARIABLE IS SET TO "TRUE"

var imagenames=new Array( 'Enter.png' , 'Enter-h.png' , 'optimised-h.png' , 'home-h.png' , 'bio-h.png' , 'resume-h.png' , 'contact-h.png' , 'FF-h.png' , 'TB-h.png' , 'W3-h.png' , 'CT-h.png' , 'Buddy-h.png' , 'IWDN-h.png' , 'Work-h.png' , 'Bg-top.png' , 'Index.png' , 'optimised.png' , 'home.png' , 'bio.png' , 'resume.png' , 'contact.png' , 'FF.png' , 'TB.png' , 'W3.png' , 'CT.png' , 'Buddy.png' , 'IWDN.png' , 'Work.png' , 'Word-h.png' , 'Word.png' , 'Text-h.png' , 'Text.png' , 'Resume-d.png' , 'Bg.png' , 'Bg-s.png' , 'Bg-top.png' );

var yposition=250; //POSITION OF LOAD BAR FROM TOP OF WINDOW, IN PIXELS
var loadedcolor='#1c5190' ; // PROGRESS BAR COLOR
var loadedimage='bg-l.png';
var unloadedcolor='#e6eef8'; // BGCOLOR OF UNLOADED AREA
var barheight=15; // HEIGHT OF PROGRESS BAR IN PIXELS (MIN 25)
var barwidth=350; // WIDTH OF THE BAR IN PIXELS
var bordercolor='#97b3d6'; // COLOR OF THE BORDER

//DO NOT EDIT BEYOND THIS POINT
var NS4 = (navigator.appName.indexOf("Netscape")>=0 && parseFloat(navigator.appVersion) >= 4 && parseFloat(navigator.appVersion) < 5)? true : false;
var IE4 = (document.all)? true : false;
var NS6 = (parseFloat(navigator.appVersion) >= 5 && navigator.appName.indexOf("Netscape")>=0 )? true: false;
var imagesdone=false;
var blocksize=barwidth/(imagenames.length);
barheight=Math.max(barheight,25);
var loaded=0, perouter, perdone, images=new Array();
var txt=(NS4)?'<layer name="perouter" bgcolor="'+bordercolor+'" visibility="hide">' : '<div id="perouter" style="position:absolute; visibility:hidden; background-color:'+bordercolor+'">';
txt+='<table cellpadding="0" cellspacing="1" border="0"><tr><td width="'+barwidth+'" height="'+barheight+'" valign="center">';
if(NS4)txt+='<ilayer width="100%" height="100%"><layer width="100%" height="100%" style="background-image: url('+loadedimage+');" bgcolor="'+unloadedcolor+'" top="0" left="0">';
txt+='<table cellpadding="0" cellspacing="0" border="0"><tr><td valign="center" width="'+barwidth+'" height="'+barheight+'" bgcolor="'+unloadedcolor+'"><center><font color="'+loadedcolor+'" size="1" face="sans-serif">Preloading Images...</font></center></td></tr></table><a href="Indexf.html"><img border="0" src="Enter.png" style="position: absolute; left: 50%; top: 0; margin-left: -400px; margin-top: -145px; visibility: hidden;" id="enter" name="enter" onmouseover="this.src=\'enter-h.png\';" onmouseout="this.src=\'enter.png\';" /></a>';
if(NS4) txt+='</layer>';
txt+=(NS4)? '<layer name="perdone" width="100%" height="'+barheight+'" bgcolor="'+loadedcolor+'" top="0" left="0">' : '<div id="perdone" style="position:absolute; top:1px; left:1px; width:'+barwidth+'px; height:'+barheight+'px; background-color:'+loadedcolor+'; z-index:100">';
txt+='<table cellpadding="0" cellspacing="0" border="0"><tr><td valign="center" width="'+barwidth+'" height="'+barheight+'" style="background-image: url('+loadedimage+');" bgcolor="'+loadedcolor+'"><center><font color="'+unloadedcolor+'" size="1" face="sans-serif">Preloading Images...</font></center></td></tr></table><a href="Indexf.html"><img border="0" src="Enter.png" style="position: absolute; left: 50%; top: 0; margin-left: -400px; margin-top: -145px; visibility: hidden;" id="enter" name="enter" onmouseover="this.src=\'enter-h.png\';" onmouseout="this.src=\'enter.png\';" /></a>';
txt+=(NS4)? '</layer></ilayer>' : '</div>';
txt+='</td></tr></table>';
txt+=(NS4)?'</layer>' : '</div>';
document.write(txt);
function loadimages(){
if(NS4){
perouter=document.perouter;
enter=document.enter;
perdone=document.perouter.document.layers[0].document.perdone;
}
if(NS6){
perouter=document.getElementById('perouter');
perdone=document.getElementById('perdone');
enter=document.getElementById('enter');
}
if(IE4){
perouter=document.all.perouter;
perdone=document.all.perdone;
enter=document.all.enter;
}
cliplayer(perdone,0,0,barheight,0);
window.onresize=setouterpos;
setouterpos();
for(n=0;n<imagenames.length;n++){
images[n]=new Image();
images[n].src=imagenames[n];
setTimeout('checkload('+n+')' ,n*100);
}}
function setouterpos(){
var ww=(IE4)? document.body.clientWidth : window.innerWidth;
var x=(ww-barwidth)/2;
if(NS4){
perouter.moveTo(x,yposition);
perouter.visibility="show";
}
if(IE4||NS6){
perouter.style.left=x+'px';
perouter.style.top=yposition+'px';
perouter.style.visibility="visible";
}}
function dispbars(){
loaded++;
cliplayer(perdone, 0, blocksize*loaded, barheight, 0);
if(loaded>=imagenames.length)setTimeout('hideperouter()', 800);
}
function checkload(index){
(images[index].complete)? dispbars() : setTimeout('checkload('+index+')', 100);
}
function hideperouter(){
(NS4)? enter.visibility="visible" : enter.style.visibility="visible";
(NS4)? perouter.visibility="hide" : perouter.style.visibility="hidden";
imagesdone=true;
}
function cliplayer(layer, ct, cr, cb, cl){
if(NS4){
layer.clip.left=cl;
layer.clip.top=ct;
layer.clip.right=cr;
layer.clip.bottom=cb;
}
if(IE4||NS6)layer.style.clip='rect('+ct+' '+cr+' '+cb+' '+cl+')';
}
window.onload=loadimages;

( Put onto the page http://stephen-cook.cavetroubles.org/Home.html )

Hope I'm not being too wanty, but can someone take me through this so I can write my own that works in all (main) browsers?

Cheers if someone can :)

P.S
(I have edited the script so that an image appears after the preloader bit's gone away)
Sorry if any of this is crappy code in any way, but basically I want someone to tell me how to do what is on http://stephen-cook.cavetroubles.org/Home.html valid in every browser. Again, hope I don't sound too wanty :blush:

inimino
July 7th, 2007, 21:23
The script you have seems to replicate that incredibly annoying "loading..." feature of Flash sites, although this is completely unnecessary on the Web, where resources are downloaded as they are needed.

Apart from that, the only pedagogical use I can see for this script is as an example of how not to write JavaScript.

What is the problem you are trying to solve?

MinatureCookie
July 7th, 2007, 21:50
Well, OnMouseOver effects of images should be displayed faster (immidiately preferably...) after an image preload, or am I mistaken?

--As in <img src="1.png" onmouseover="this.src='2.png';" />
2.png will not take ages to show.

MinatureCookie
July 8th, 2007, 00:04
Is there a simpler way to do this? I'm very open to suggestions.

Pattons3rd
July 8th, 2007, 03:42
This is something I use, and it seemed to work pretty well.

Very basic really, I was very confused at first by all the long codes and stuff.


So here is the Javascript.
var about_over = new Image();
var faq_over = new Image();
var home_over = new Image();
var about = new Image();
var home = new Image();
var faq = new Image();
about_over.src="pics/about_over.gif";
faq_over.src="pics/faq_over.gif";
home_over.src="pics/home_over.gif";
faq.src="pics/faq.gif";
about.src="pics/about.gif";
home.src="pics/home.gif"

And then the HTML <a class="navbar" href="index.html" onmouseover="Home.src=home_over.src" onmouseout="Home.src=home.src"><img name="Home" src="pics/home.gif" alt="Home" border="0" align="middle" hspace="0" vspace="0" /></a>
<br />
<br />
<a class="navbar" href="about.html" onmouseover="About.src=about_over.src" onmouseout="About.src=about.src"><img name="About" src="pics/about.gif" alt="About Us" border="0" /></a>
<br />
<br />
<a class="navbar" href="faq.html" onmouseover="Faq.src=faq_over.src" onmouseout="Faq.src=faq.src"><img name="Faq" SRC="pics/faq.gif" border="0" alt="FAQ" /></a>

I hope this can help you!

inimino
July 8th, 2007, 03:48
Sure, there are several ways of doing this. The simplest is to add <img> elements for each image on the page, and use CSS to hide them. You can also use JavaScript. Another technique, which BigBison will probably recommend if he sees this thread, is to use one image per button, and use CSS to change the part of the image that is shown for the rollover effect. This is fastest as the browser only has to download one image instead of two.

Regardless of how you preload the images, the best way to get the effect is to use CSS rather than JavaScript.

MinatureCookie
July 8th, 2007, 11:17
Okay, could you walk me into that last one about using one image per button?... I don't quite understand what you mean by that :lol:

inimino
July 9th, 2007, 11:22
Start with BigBison's posts in this thread:

http://www.iwdn.net/showthread.php?t=6418

MinatureCookie
July 9th, 2007, 18:53
Okay, I've applied it and it works in FireFox :-)
But it doesn't work in IE, it only displays the text... Have I done something in my code, or does this just not work in IE?
http://stephen-cook.cavetroubles.org/

ul#navbar{
width:166px;
height:32px;
margin:0 auto;
}
ul#navbar li{
float:left;
height:32px;
display:block;
text-align:center
}
ul#navbar li a{
position:relative;
height:32px;
display:block
}
ul#navbar li a span{
position:absolute;
top:0;left:0;
display:block;
height:32px
}
li#indexButton,li#indexButton a span{width:113px}
li#indexButton a span{background:url(optimised-index.png) no-repeat center center}
li#bioButton,li#bioButton a span{width:166px}
li#bioButton a span{background:url(optimised-bio.png) no-repeat center center}
li#workButton,li#workButton a span{width:107px}
li#workButton a span{background:url(optimised-work.png) no-repeat center center}
li#resumeButton,li#resumeButton a span{width:135px}
li#resumeButton a span{background:url(optimised-resume.png) no-repeat center center}
li#contactButton,li#contactButton a span{width:135px}
li#contactButton a span{background:url(optimised-contact.png) no-repeat center center}
ul#navbar li a span{background-position:0 0px}
ul#navbar li a:hover span{background-position:0 -38px}
ul#navbar li a:active span{background-position:0 -38px}


<div style="margin-left: -35px; margin-top: 20px;"
<ul id='navbar'>
<li id="indexButton"><a title="Home" href="Indexf.html">Home<span></span></a></li><br /><br /><br />
<li id="bioButton"><a title="Web Design" href="Biography.html">Biography<span></span></a></li><br /><br /><br />
<li id="workButton"><a title="Search Engine Optimisation" href="Work.html">Work<span></span></a></li><br /><br /><br />
<li id="resumeButton"><a title="Search Engine Optimisation" href="Resume.html">Resume<span></span></a></li><br /><br /><br />
<li id="contactButton"><a title="Contact" href="Contact.html">Contact<span></span></a></li><br /><br /><br />
</ul>
</div>

That's my code (CSS then HTML)

MinatureCookie
July 9th, 2007, 19:21
^^ URL up there won't work :P
http://stephen-cook.cavetroubles.org/indexf.html

Pattons3rd
July 9th, 2007, 20:03
Umm, just to let you know on line 70 of your code, the <div> tag is left unfinished....

http://validator.w3.org/check?uri=http%3A%2F%2Fstephen-cook.cavetroubles.org%2Findexf.html

XHTML doesn't allow <br />'s inside of lists, as I just happened to find out today..... (http://www.iwdn.net/showpost.php?p=67146&postcount=3) :whistle:

This is something like I am working on, so I shouldn't be talking....:slap:


BTW, looks great....

MinatureCookie
July 9th, 2007, 21:34
Whoops :S
And grr, I'll add a margin-top then :P
(Cheers by the way)
I'll quickly fix the problems, but I doubt it will fix the IE thing... But I've been proven wrong before :lol:
-Well, if you'll care to look at it now on IE, I'll be damned it worked :P
Cheers :)

-May just be my IE, but I take it back; it's not working properly: it seems to do the onmouseover but not the onmouseout...?

chaos
July 9th, 2007, 23:54
Looks like it's working great now in Internet Explorer 6. I would test it in IE7, but I have chosen not to taint my fresh install of XP with such filth ;) Looks like you implemented the CSS very well, and congrats.

Pattons3rd
July 9th, 2007, 23:58
It looks pretty good in IE7, I am just not too sure what you wanted.
Was the menu going up with small windows and down with large on purpose?

And how close or far from the divider bar did you want the menu?

MinatureCookie
July 10th, 2007, 16:52
I've seen it in IE7 and doesn't look right, but it's just a little thing FF will read but IE7 refuses to... But I'm just quickly changing that now :)
++For future reference the problem was I had the background image applied to the <span> tag instead of the <a> which IE couldn't read properly (Thanks to Chaos for the help there ;))