Link to home
Start Free TrialLog in
Avatar of KE
KE

asked on

Crossbrowser Progressbar

I need a progressbar that works on both IE4 and NS4. I would prefer not to have images in it, to reduce DL time. Also I need to update the progressbar from an image preloader. I've tryed to use the DIV tags with some style properties, but I can't get it to work properly. Anyone that have a working example or a link ?

Basically what I want is to have my mainpage preload all images before I show the next page. The mainpage should show the progress of this, and I would like to include the preload feature with a single script line - like:

<script>imgpreload([...array of urls...]);</script>

The script should insert the progressbar at this position, and start loading the images while updating the progressbar. There may be additional parameters to indicate the width and height.

Regards

Regards
Avatar of Michel Plungjan
Michel Plungjan
Flag of Denmark image

The best image preloader I have seen is using the images you preload as progress - No waste!

You need to include the script that actually does the job too - a oneliner will be huge ;-)

It could even be made to sort of work in IE3...

If you wish I can make you one like that (unless someone is going to answer this with something else while I work (hint, hint))

Michel
<html>
<head>
<title>Image preload progress bar</title>
<script language="JavaScript"><!-- // cloak
/* Image preload progress bar
   (c) 2000 Michel Plungjan michel@irt.org */
theImages = new Array(
'earth01.gif',
'earth02.gif',
'earth03.gif',
'earth04.gif',
'earth05.gif'
);

function makeProgress(pw,h) {
   var text ="";
   var w = parseInt(pw/theImages.length);
   if (w < 10) w = 10;
   if (document.images) {
      for (i=0;i<theImages.length;i++) {
         text += '<img \nname="img'+i+'" width='+w+' height='+h;
         if (i>0) text += ' src="blank.gif"'
         else text += ' src="'+theImages[i]+'"'
         if (i==(theImages.length-1)) text += '>';
         else text += ' onLoad="document.images[\'img'+(i+1)+'\'].src=theImages['+(i+1)+'];">';
      }
   }
   else {
      for (i=0;i<theImages.length;i++) {
         text += '<img src="'+theImages[i]+'" width='+w+' height='+h+'>';
      }
   }
   return text;
}


// uncloak --></script>
</head>
<body>


<script language="JavaScript"><!-- // cloak
document.write(makeProgress(400,32));
// uncloak --></script>
</body>
</html>
Just fill the array with images (remember ot not have a comma afte te last one) and give the function the width and height of the progress bar.

Michel
Sorry tiny bug (the script is triggered on the blank too)

I will fix it in a sec

Michel
Hmm I seem to have found a bug in IE5!!!

Can anyone fix this script for IE???

<html>
<head>
<title>Image preload progress bar</title>
<script language="JavaScript"><!-- // cloak
/* Image preload progress bar
   (c) 2000 Michel Plungjan michel@irt.org */
   
theImages = new Array(
'earth00.gif',
'earth01.gif',
'earth02.gif',
'earth03.gif',
'earth04.gif',
'earth05.gif'
);

function makeProgress(pw,h) {
   var text ="";
   var w = parseInt(pw/theImages.length);
   if (w < 10) w = 10;
   if (document.images) {
      for (i=0;i<theImages.length;i++) {
         text += '<img \nname="img'+i+'" width='+w+' height='+h;
         if (i>0) text += ' src="blank.gif"'
         else text += ' src="'+theImages[i]+'"'
         if (i==(theImages.length-1)) text += '>';
         else {
            text += ' onLoad="alert(\'hello\'+'+(i+1)+');loadNext('+(i+1)+');">';
         }
      }
   }
   else {
      for (i=0;i<theImages.length;i++) {
         text += '<img src="'+theImages[i]+'" width='+w+' height='+h+'>';
      }
   }
document.write('<x'+'mp>'+text+'</x'+'mp>');
   return text;
}
curImg = 1;
blanks = 0;
done = false;
window.loaded = false;
function loadNext(theIndex) {
   if (!window.loaded) return;
   alert(theIndex+ "!=" +curImg);
   if (theIndex != curImg) return;
   document.images['img'+curImg].src=theImages[curImg];
   curImg++;
}

// uncloak --></script>
</head>
<body onLoad="window.loaded=true;loadNext(1);">


<script language="JavaScript"><!-- // cloak
document.write(makeProgress(400,20));
// uncloak --></script>
</body>
</html>
Avatar of kollegov
kollegov

Here is my solution:
--------file:progressbar.js--------
/* CrossBrowser progress bar
 * copyright Virtual_Max, 2000
 * http://come.to/vmax
 * Can be used/modified absolutely free untill this
 * statement presents in all copies and derivatives
 */

var barw;
var bgcolor;

function progressShow(vis)
 {
  if(document.all)
   {dddd=document.all['pbar'].style;
    dddd.visibility = vis ? "visible":"hidden";
   }
  if(document.layers)
   {dddd=document['pbar'];
    dddd.visibility = vis ? "show":"hide";
   }
 }

function setupProgressBar(top,left,width,color){
s='<style>'
s+='#pbar{width:'+width+';position:absolute;top:'+top+';left:'+left+';';
s+='background-color:'+color+';clip:rect(0,0,10,0);}</style>';
document.writeln(s);
s='<div ID="pbar">;&nbsp;</div>'
document.writeln(s);

barw=width;
bgcolor=color;
}
function showProgress(n){
 if(document.all){
  o=document.all['pbar'];
  w=Math.floor(barw*n);
  o.style.clip="rect(0,"+w+",10,0)";
 }
 if(document.layers){
  o=document['pbar'];
  w=Math.floor(barw*n);
  o.clip.width=w;
  o.bgColor=bgcolor
 }
}
---------------------------------------
This is general purpouse progress bar, you can use it to display anything.

There are 2 main functions
function setupProgressBar(top,left,width,color)
and
function showProgress(n)
where n is float from 0 to 1

Example of usage with image prloading script:
----------------------------------------
<html>
<head>
<script src="progressbar.js"></script>
</head>
<script>
 ims = new Array();

//preload images
 function startImageLoader(){
   args = startImageLoader.arguments
   for(var i=0;i<args.length;i++){
     ims[i]=new Image();
     ims[i].errored=false;
     ims[i].onerror=new Function("ims["+i+"].errored=true");
     ims[i].src=args[i];
   }
  updateProgress();
 }

 function updateProgress(){
   var cnt=0;
   for(var i=0;i<ims.length;i++){
     if(ims[i].complete || ims[i].errored) cnt++;
     
   }
   if(ims.length>0){
     showProgress(1.0*cnt/ims.length);
     window.status=""+cnt;
   }
   if(cnt<ims.length){
    setTimeout("updateProgress()",200);
   }
   else{
      onComplete();
   }
 }

function onComplete(){
   // do here whatever you need when
   // loading complete
   alert("Done!");
   progressShow(false);
}

</script>

<body>
<script>
/* set bar with top,left,width,color */
setupProgressBar(100,20,200,"#000080");
//initial state
showProgress(0);

//preload this images
//you can specify as much as needed

startImageLoader(
"http://www.geocities.com/virtual_max/vmaxtree/icons/arrow_gold.gif",
"http://www.geocities.com/virtual_max/vmaxtree/icons/arrow_cyan.gif",
"http://www.geocities.com/virtual_max/vmaxtree/icons/movie_gray.gif",
"http://www.geocities.com/virtual_max/vmaxtree/icons/folder_cyan.gif",
"http://www.geocities.com/virtual_max/vmaxtree/icons/ofolder_cyan.gif",
"http://www.geocities.com/virtual_max/vmaxtree/icons/folder_mokko.gif"
);
</script>
</body>

</html>


Script tested with NN4.7, MIE5.01
WinNT

Virtual_Max

ASKER CERTIFIED SOLUTION
Avatar of kollegov
kollegov

Link to home
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.
Start Free Trial
Opppsss, sorry for duplicate
Any chance of fixing my script for IE? (much smaller)

Michel
Avatar of KE

ASKER

mplungjan: Very good solution. However I'm looking for a "solid" progress bar style - like in kollegov's example.

kollegov: Ány chance of having this work with relative positioning. I've tryed to implement a <div style="postion:relative"> around the current DIV tag, but then NS doesn't show anything (as usual :-).

Thanks to both of you, your help is REALLY appreciated - thanks !

Regards
Avatar of KE

ASKER

BTW. Can I have the progressbar in one include file, like: "progress.js" and the image loader in another, like "imgpreload.js" where I then reference "progressbar.js".

I don't know wether it's possible to include scripts within included scripts.

Regards
Using document.write you can, but you shouldn't...
Just include both files in the same page
Michel
It's more problems to fix it for MIE :)
As soon as I changed to relative clipping stopped working! Thus I changed clipping to changing width...
One more problem remains unsolved ...
In MIE <div> act as linebreaks..
It's not a problem if this will be nested somewhere in table, but makes a bit wired positioning inside text.

-----progressbar.js-----
/* CrossBrowser progress bar
 * copyright Virtual_Max, 2000
 * http://come.to/vmax 
 * Can be used/modified absolutely free untill this
 * statement presents in all copies and derivatives
 */

var barw;
var bgcolor;

function progressShow(vis)
 {
  if(document.all)
   {dddd=document.all['pbar'].style;
    dddd.visibility = vis ? "visible":"hidden";
   }
  if(document.layers)
   {dddd=document.wrapper.document['pbar'];
    dddd.visibility = vis ? "show":"hide";
   }
 }

function setupProgressBar(top,left,width,color){

s='<style>'

if(document.layers){
 tag='layer';
 s+='#pbar{width:'+width+';position:absolute;top:0;left:0;';
}

else{
 tag='div';
 s+='#pbar{width:'+width+';position:relative;top:0;left:0;';
}

s+='background-color:'+color+';clip:rect(0,0,20,0);}</style>';
document.writeln(s);

s='';
if(document.layers){
  s+='<ilayer ID="wrapper" height=25 width='+width+'>';
}

s+='<'+tag+' ID="pbar" width='+width+'></'+tag+'>';

if(document.layers) {
  s+='<spacer type="block" width='+width+' height=20>';
  s+='<ilayer>'
}


document.writeln(s);

barw=width;
bgcolor=color;
}

function showProgress(n){
 if(document.all){
  o=document.all['pbar'];
  w=Math.floor(barw*n);
  // what idot invented this order of clip ???
  // top,right,bottom,left
  o.style.clip="rect(0,"+w+",10,0)";
  o.style.width=w;
 }
 if(document.layers){
  o=document.wrapper.document['pbar'];
  w=Math.floor(barw*n);
  o.clip.width=w;
  o.bgColor=bgcolor
 }
}
------------


<html>
<head>
<script src="progressbar.js"></script>
</head>
<script>
 ims = new Array();

//preload images
 function startImageLoader(){
   args = startImageLoader.arguments
   for(var i=0;i<args.length;i++){
     ims[i]=new Image();
     ims[i].errored=false;
     ims[i].onerror=new Function("ims["+i+"].errored=true");
     ims[i].src=args[i];
   }
  updateProgress();
 }

 function updateProgress(){
   var cnt=0;
   for(var i=0;i<ims.length;i++){
     if(ims[i].complete || ims[i].errored) cnt++;
     
   }
   if(ims.length>0){
     showProgress(1.0*cnt/ims.length);
     window.status=""+cnt;
   }
   if(cnt<ims.length){
    setTimeout("updateProgress()",200);
   }
   else{
      onComplete();
   }
 }

function onComplete(){
   // do here whatever you need when
   // loading complete
   alert("Done!");
   progressShow(false);
}

</script>

<body>
loading progress:
<script>
/* set bar with top,left,width,color */
setupProgressBar(100,20,200,"#000080");
//initial state
showProgress(0);

//preload this images
//you can specify as much as needed

startImageLoader(
"http://www.geocities.com/virtual_max/vmaxtree/icons/arrow_gold.gif",
"http://www.geocities.com/virtual_max/vmaxtree/icons/arrow_cyan.gif",
"http://www.geocities.com/virtual_max/vmaxtree/icons/movie_gray.gif",
"http://www.geocities.com/virtual_max/vmaxtree/icons/folder_cyan.gif",
"http://www.geocities.com/virtual_max/vmaxtree/icons/ofolder_cyan.gif",
"http://www.geocities.com/virtual_max/vmaxtree/icons/folder_mokko.gif
);
</script>
isn't it cool ????
</body>

</html>

If you replace the line tag='div'; with tag='span' in the code above you will not get the linebreak behaviour like you do with the div tag.
 
Avatar of KE

ASKER

Hmmm... Am I doing something wrong ?

This is my code for inserting the progressbar:

<table border="0" cellpadding="0" cellspacing="0">
      <tr>
            <td>TEST</td>
      </tr>
      <tr>
            <td>
<script>
// set bar with top,left,width,color
setupProgressBar(0,0,200,"#000080");
</script>
            </td>
      </tr>
</table>

Works fine with IE, but NS don't care about the table - the progressbar is positioned at the top-left corner (0,0) absolute...

Regards
Avatar of KE

ASKER

Adjusted points from 100 to 150
Avatar of KE

ASKER

Well, I solved the "relative" problem on my own, and everything is working now.

Thanks to everyone participating, very appreciated... I will let kollegov get the points as my solution is closest to his work - and also because I've used parts of his code.

Regards