View Full Version : Image preloads
shashgo
10-21-2002, 04:19 AM
Hey,
I have a wscript that has a hundred or so images to preload. Each of these image names might be existant or not, so I test the existence using img.onload and the nonexistence using img.onerror.
But the preloading of each image requires some time, otherwise they always give an error. So I coded a setTimeout with a delay.
But how would I know what is an appropriate delay? And even if I set the delay to an appropriate value, how can I kep the user entertained while the images are preloading?
The script is
--------
var numImages=0;
var imgArray=new Array();
var imgNum;
var Number=134;
var Current=1;
var td=setInterval("loadEm()",1000);
function loadEm()
{
pic=new Image();
pic.onerror=function(){document.frm.disp.value="Picture "+Current+" not loaded";};
pic.onload=function()
{
imgArray[numImages]=new Image();
imgArray[numImages].src=this.src;
document.frm.disp.value="Picture "+Current+" loaded as imgArr["+numImages+"]";
numImages++;
}
pic.src=Current+".jpg";
if (Current<Number)
{
Current++;
}
else
{
clearTimeout(td); //Stop the recurring calls because of the setInterval mthod
Current=numImages-1; //Set Current to point to the last element image of the array
document.frm.b.disabled=false;
}
}
Also, if I want the window to display fullscreen while displaying th images, I say window.open('','','fullscreen=1'). How do I link to another window from there and have that new window display normal size?
beetle
10-21-2002, 08:30 AM
Shashgo, didn't you see my test page? (http://www.peterbailey.net/test/) I mentioned it in your last post (http://www.codingforums.com/showthread.php?s=&threadid=8324&highlight=imgArray) on this very same subject (BTW, you really shouldn't keep posting new threads for the same problem, from the search I did, this is your 4th)
Anyhow, moving along. You can't determine the delay. Modems will surely load the images far slower than DSL lines. You will notice on my test page that the largest images tend to load last, as expected. If you knew exactly how many images to expect, then some things could be done...but from what I gather from all your other posts, is that you DON'T know this information ahead of time...
shashgo
10-21-2002, 10:20 AM
Beetle,
I deleted one earlier email from codingforums, and I guess that was the one in which you had sent me the test page.
I looked at it right now, and my guess is that the images preload so quickly because the total number of images is only 12 or 13. It would take a lot longer for 100 or so images to load. And I ned the time delay for that. So I was wondering if there was a way to find out somehow how much the delay for each image should be. Probably not, from what you said. In that case, how can I keep the user entertained while he is waiting for the images to preload?
beetle
10-21-2002, 03:15 PM
Yes you most certainly WILL NOT be able to determine the time required. Also, since you don't know the exact number of images being loaded, you won't be able to give the end user any type of feedback when all of them are loaded either.
However, since the script I wrote puts the quickest loading images into the array first...the slideshow can be viewed shortly after visiting the page...and each image has (n*delay) seconds longer to load than the first image. So the 10th image in the slideshow shown with a 2 second delay has a full 20 seconds to load, even if slideshow is started immediately.
How do you entertain your users? I think that's up to you.
shashgo
10-21-2002, 04:45 PM
Beetle,
Question. How do you get th code to decide which is the largest picture size?
beetle
10-21-2002, 05:19 PM
You don't. JS cannot read filesize.
shashgo
10-21-2002, 05:38 PM
Beetle,
Can you tell me what getElementbyId() and innerHTML and outerHTML are? I havent seen those words before.
Can you give me a line by line listing of the test page source with comments? I guess I dontknow as much javascript since I dont know some terms youve used
beetle
10-21-2002, 05:59 PM
Sure, I'll do my best
getElementById(id)
This is a method of the document that retrieves an object reference based on the object's ID, which we pass to the method (methods are functions that are attached to objects) as a string. This is the standard way to reference an object within an HTML page.
innerHTML and outerHTML
These properties apply to most any HTML element. They are used to read/write the element's HTML as text. So, in this example...
<p>Hello <b>World!</b></p>the innerHTML yields "Hello <b>World!</b>" and the outerHTML yields "<p>Hello <b>World!</b></p>". Note: there is also an innerText property that ignores HTML markup, and in this case would yield "Hello World!".
As for the code with explanation...here goes:var loadingArray = new Array();
var imgArray = new Array();
var imgNum;
var current=0;
var pause, pic;
var imgRoot = "images/";
function loadEm() {
for (var i=1,j=0;i<=13;i++) {
// Creates new image object in loadingArray
loadingArray[i] = new Image();
// Sets the source
loadingArray[i].src=imgRoot+i+".jpg";
// Runs function if error (file not found)
loadingArray[i].onerror = function() {
// Adds error message to output area
document.getElementById('output').innerHTML += "File not found: "+this.src+"<br>";
}
// Runs function when image is fully loaded
loadingArray[i].onload = function() { addImage(this, j++); }
}
}
function addImage(img, index) {
// Adds image object to imgArray
imgArray[index] = img;
// Adds message to output area
document.getElementById('output').innerHTML += "Added "+img.src+" to imgArray["+index+"]<br>";
}
function inter() {
pause = prompt("Number of images loaded "+imgArray.length+"\nEnter interval for slideshow","2");
pause *= 1000;
disp();
}
function disp() {
// Sets the source for the slideshow image
document.getElementById('nisha').src=imgArray[current].src;
// Sets the status text
document.getElementById('status').firstChild.nodeValue = "Picture "+(current+1)+" : "+imgArray[current].src;
// Control slideshow counter for looping
current = (current == imgArray.length-1) ? 0 : current += 1;
// Loops slideshow
setTimeout("disp();",pause);
}
shashgo
10-22-2002, 05:38 PM
Beetle,
Your code explanation is pretty helpful, especially the div stuff to make sections on the page.
What I gather is that by pressing the start slideshow button, the slideshow will begin even if the loadem() function hasnt finishing loading all the images. Is that right?
What Im confused about is where do you tell the code that it has to load the quickest loadeing images first, ....or is it just that you have the images arranged on your drive this way, so that when the images start loading, the quickest loading ones are automatically loaded first?
In the statement
document.getElementById('status').firstChild.nodeValue = "Picture "+(current+1)+" : "+imgArray[current].src;
what is firstChild and nodeValue?
If you have a section marked off by the tags <div id="one"</div> in the body, then you write to this section with the javascript statement
document.getElementById('one').innerHTML += "Just some text";
Correct?
Then how come I cant get it to work?
What I want to do is to insert a bunch of images into a table and have that table display in another larger table in one of the cells?
beetle
10-22-2002, 06:34 PM
Ok...first of all, the image loading. I don't and cannot specify which images will load first. The onload event that is attached to each new image-object fires when the image file has been fully loaded (read: completely downloaded). Because by their very nature of being big or small, the smallest images (filesize-wise, not dimensions) load first, and the largest ones load last (which also means thier onload event fires later than the others) Do we understand this?
Ok, about firstChild and nodeValue. Let's look at this HTML<div="status">Hello</div>To the DOM (Document Object Model) this HTML has a heirarchial structure, which can be expressed in tersm of parents and children. When speaking in terms of the DOM, HTML elements and text are referred to as nodes. So, as the DOM sees this HTML, it looks like this...<DIV#status>
-> #textNode(Hello)As you can see, the textNode with the value 'Hello' is a child do the DIV, and conversely, the DIV is the textNode's parent.
Now that we understand (hopefully) that relationship, you can see that a statement likedocument.getElementById('status').firstChildObtains a reference to the textNode. The nodeValue property applies to textNodes, and reads/writes their text value as a string.
On to your last question (problem). If you are trying to write to the object's innerHTML before the object has loaded, then you will get an error. HTML is read left-right top-down by the browser...so if the code that manipulates an object appears before the object itself (in source order), then you will get an error. The exception to this source-order rule, of course, is when the scripting lay within functions that are called after the document (and all it's objects) have fully loaded.
Whew! Did I miss anything?
Visit the MSDN, Gecko, and xBrowser links in my signature for more information.
shashgo
10-22-2002, 07:27 PM
beetle,
Wow! What a handful. Good explanation.Quite helpful. I have not understood everthing you said but im going to continue studying it.
What I want to do is something like have a script generate several images and then display them in a particular cell of a table on my page.
I can use the image loading program you sent for this, which will start displaying images while loading the rest. (It is automatic, from what I understand of your explanation, that quicker images load first because of the onload method. Hope Im right in this understanding)
If I were to just use a loop to append each additional image to a string and then display the string via a document.write then ii wont have the images displayed ina table within the bigger table I have on the page.
So something like
msg="<table><tr>";
for (i=1;i<20;i++)
{
msg+="<td><img src=imgArray[i].src></td>";
if (i%10==0) msg+="</tr><tr>;
}
msg+="</tr></table>";
document.write(msg);
wont write the msg within a cell of the bigger table that i have on my page. Is there any way I can do this, that is target a cell in a table to write stuff to?
beetle
10-22-2002, 07:47 PM
Whoa whoa whoa. You have to put aside the concept of manipulating a page's HTML as text, building strings like that and so forth. Not to mention the fact that the method you are using will kill the current document object (if a document object is fully loaded, and you THEN try to write to it, a NEW document object will be created...destroying the current one)
Everything we've looked at so far (except for innerHTML and outerHTML) interacts with the HTML on the page via the DOM.
It looks like you are tyring ot create a 2 row, 10 column table, do I have that right?
shashgo
10-22-2002, 08:51 PM
Beetle,
Yes I know a document.write will kill the current page.
You understood corretly what I want . I have a table with 3 rows and two columns. I want to insert this small table (the one with the images) into the middle rwo, right column. So , in effect, it will be a nested table.
How do I do that
beetle
10-22-2002, 09:32 PM
Well, the answer is both simple and comlicated. Once you have a decent grasp on the tools, the solution is quite simple...but until you do have that grasp, this might be confusing as heck.<html>
<head>
<title>Test</title>
<script>
function makePicTable() {
var tr, td, img, i, j;
var r = 2;
var c = 10;
var counter = 0;
var t = document.createElement("TABLE");
t.setAttribute("border","1px");
for (i=0; i<r; i++) {
tr = t.insertRow();
for (j=0; j<c; j++) {
td = tr.insertCell();
img = document.createElement("IMG");
img.setAttribute("src",imgArray[counter].src);
td.appendChild(img);
}
counter++;
}
document.getElementById('myTable').rows[1].cells[1].appendChild(t);
}
</script>
</head>
<body onLoad="makePicTable();">
<table id="myTable" border="1" width="760">
<tr>
<td>Hello</td><td>Hello</td>
</tr>
<tr>
<td>Hello</td><td></td>
</tr>
<tr>
<td>Hello</td><td>Hello</td>
</tr>
</table>
</body>
</html>
shashgo
10-23-2002, 12:29 AM
Beetle,
Youre right in one aspect. It is both simple and complicated. But not too complicated because I understand it.
This is one way to do. I have another script thqat doesnt work quite right.
<html>
<head>
<script language="javascript">
msg="<table><tr>";
for (i=1;i<20;i++)
{
msg+="<td><img src=imgArray[i].src></td>";
if (i%10==0) msg+="</tr><tr>;
}
msg+="</tr></table>";
document.write(msg);
</script>
</head>
<body>
<table>
<tr>
<td> </td>
<td name="mycell"></td>
</tr
</table>
<body>
</html>
kinda works, but there are two snafus: 1) how do i write the line
msg+="<td><img src=imgArray[i].src></td>";
so that i can make sure that the value of imgArray[i]/src is assigned to img.src instead of nothing since imgArray[i].src is not the name of a file.
And finally can the name mycell be used to refer to the cell, so that msg can be written to that cell.
beetle
10-23-2002, 05:14 PM
Like this
msg+="<td><img src=\""+imgArray[i].src+"\"></td>";
vBulletin® v3.8.2, Copyright ©2000-2012, Jelsoft Enterprises Ltd.