Welcome to WebmasterWorld Guest from 54.197.116.116

Forum Moderators: open

Message Too Old, No Replies

js test for "is image loaded"?

can't get document.images[name].onLoad to work....

   
9:29 am on Jun 28, 2002 (gmt 0)

10+ Year Member



Hello,

I've had to strip out all the images on our 'work' section as they were making the page weigh in cloes to 1MB OUCH!
I've been working on this Javascript

<script language="JavaScript">
function flip(name,src) {
if (navigator.appName == "Microsoft Internet Explorer") {
document.all.wait.style.visibility="visible";
}
else {
document.layers["wait"].visibility = "visible";
}
swapImage='images/clients/'+src
if (document.images){
document.images[name].src = swapImage;
imageTimeout = setTimeout('loadTest(name)',1000);
}
}
function loadTest(name){
if (document.images){
document.images[name].onLoad=showImage();
}
}
function showImage() {
//remove this alert when fixed....
alert("loaded");
if (navigator.appName == "Microsoft Internet Explorer") {
document.all.wait.style.visibility="hidden";
}
else {
document.layers["wait"].visibility = "hidden";
}
}
</script>
I inserted a timeout to see wether that would help, as before the onload would trigger instantly. It basically should show the 'wait' layer untill the image is loaded. Any ideas on how i can overcome this problem much appreciated.
BenG
4:03 pm on Jun 28, 2002 (gmt 0)

10+ Year Member



onload() (note: lower case, since all except MSIE are case sensitive) should be invoked when the object has completed loading, but as your experience shows, it seldom waits that long. The same is true with <body onload="..."> to many people's frustration (including mine).

The Image object has a property called Image.complete, which is true when downloading is complete (I can't offhand remember whether it is also true when an error has occured and the download has been aborted). You can build a function like this:

function waitFor(img){
if(!img.complete){
imgWait=setTimeout('waitFor(img)', 250);
}
else{
// Code to execute on completion of download
}
}

I've assigned the return value of the timeout to a variable. This is so that you can set the image's onerror() and onabort() handlers to cancel the timeout if the image is broken or the user hits the Stop button respectively.

4:21 pm on Jun 28, 2002 (gmt 0)

10+ Year Member



hey that looks good, mac/pc i hope. i'm about to leave work will try it on monday, thankyou! have a good weekend
4:28 pm on Jun 28, 2002 (gmt 0)

10+ Year Member



quickly tried this
function flip(name,src) {
if (navigator.appName == "Microsoft Internet Explorer") {
document.all.wait.style.visibility="visible";
}
else {
document.layers["wait"].visibility = "visible";
}
swapImage='images/clients/'+src
if (document.images){
document.images[name].src = swapImage;
// this onload event isn't working properly, triggers instantly....
waitFor(name)
//clearTimeout(imageTimeout);

}
}
function waitFor(img){
if(!img.complete){
imgWait=setTimeout('waitFor(img)', 250);
}
else{
showImage()
}
}

returned 'img' undefined....
9:31 pm on Jun 29, 2002 (gmt 0)

10+ Year Member



Right. First, your browser detection script is, um, lousy. It will break in everything except MSIE and NN4. A better solution is this:

if(document.layers){
// Code for NN4
}
else{
// Code for most everything else
}

(OK, that's not perfect either, but it will work for NN6, for example.)

Second, waitFor() expects an Image object. You have given it the variable called name, which contains a string. Where you have:

waitFor(name)

you need:

waitFor(document.images[name])

9:18 am on Jul 1, 2002 (gmt 0)

10+ Year Member



thanks for the browser script test, that was bad of me.

I have a very strange error now. If i add an alert the script works great, when i remove the alert i still get 'img' is undefined..

function flip(name,src) {
if (document.layers) {
document.layers["wait"].visibility = "visible";
}
else {
document.all.wait.style.visibility="visible";
}
swapImage='images/clients/'+src
if (document.images){
document.images[name].src = swapImage;
waitFor(document.images[name])
}
}
function waitFor(img){
alert(img);
if(!img.complete){
imgWait=setTimeout('waitFor(img)', 250);
}
else{
showImage()
}
}
Not quite sure of how to fix it.
9:55 am on Jul 1, 2002 (gmt 0)

10+ Year Member



just tested it on a 56k modem and it doesn't work with/out the alert. i tried adding
function waitFor(img){ 
if(!img.complete){
imgWait=setTimeout('document.images[name]', 250);
}
else{
showImage()
}
}
which stopped the 'img' undefined error. But the name may not be in the scope either.
10:00 am on Jul 1, 2002 (gmt 0)

10+ Year Member



i wish u could edit posts... obviously meant:

imgWait=setTimeout('waitFor(document.images[name])', 250);

7:57 pm on Jul 1, 2002 (gmt 0)

10+ Year Member



I can edit posts -- but only during the same session. When you first make a post, there's an "Owner edit" icon on the left which you can use.

Hmm, what a curious thing. I don't generally mess around with DHTML or recursive functions, but there would appear to be an issue recursively calling a function and passing its own properties to itself.

I suppose the preferred solution would be to use the arguments[] array, but I think there are both forward and backward compatibility issues with that...

10:06 am on Jul 2, 2002 (gmt 0)

10+ Year Member



Thankyou for your help, I have finally got a working solution, so i'll post it here
<script language="JavaScript">
function init(){
preloadvar=false;
}
function flip(name, src) {
if(eval(name+'var')==false){
if (document.layers) {
document.layers["wait"].visibility = "visible";
}
else {
document.all.wait.style.visibility="visible";
}
swapImage='images/clients/'+src
document.images[name].src = swapImage;

}else{
}
eval(name+'var="true"');
}
function showImage() {
if (document.layers) {
document.layers["wait"].visibility = "hidden";
}
else {
document.all.wait.style.visibility="hidden";
}
}
</script>

and the following is placed on the blank image
 <img src="images/clients/blankhead.gif" width="333" height="231" name="preload" onLoad="if (this.src.indexOf('blankhead')==-1) showImage()">
regards Ben
3:22 pm on Jul 3, 2002 (gmt 0)

10+ Year Member



My image preload function:


function preloadImg(image){
counter = preloadImages.length;
preloadImages[counter] = new Image();
preloadImages[counter].onerror = function() { alert("Image file '" +image+ "' could not be loaded!"); }
preloadImages[counter].src = image;
}
3:39 pm on Jul 3, 2002 (gmt 0)

10+ Year Member



thanks for the input. My problem was that i needed the image to load when the user requests that image onClick, and show a layer saying "image loading" whilst loading.
8:32 am on Jul 8, 2002 (gmt 0)

WebmasterWorld Senior Member 10+ Year Member



The error you were getting with your earlier code would be down to this line

setTimeout('waitFor(document.images[name])', 250)

The setTimeout evaluates the string 'out of scope' so in 250 milliseconds when the

waitFor(document.images[name])
instruction went to execute the
name
variable wouldn't exist. This is a common problem and is fixed by writing the value of the name out using concatenation:

setTimeout('waitFor(document.images["' + name + '"])', 250)

Obviously - this doesn't work if you're passing whole objects as parameters.