views:

2287

answers:

3

I want to know when an image has finished loading. Is there a way to do it with a callback?

If not, is there a way to do it at all?

+4  A: 

Image.onload() will often work.

To use it, you'll need to be sure to bind the event handler before you set the src attribute.

Related Links:

Example Usage:

<html>
<head>
<title>Image onload()</title>
</head>
<body>

<img src="#" alt="This image is going to load" id="sologo"/>

<script type="text/javascript">
window.onload = function () {

    var logo = document.getElementById('sologo');

    logo.onload = function () {
        alert ("The image has loaded!");     
    };

    setTimeout(function(){
        logo.src = 'http://stackoverflow.com/Content/Img/stackoverflow-logo-250.png';         
    }, 5000);
};
</script>
</body>
</html>
keparo
FYI: According ot the W3C spec, onload is not a valid event for IMG elements. Obviously browsers do support it, but if you care about the spec and are not 100% sure all of the browsers you want to target support this, you may want to rethink it or at least keep it in mind.
Jason Bunting
Exactly right. Be sure to test, especially if you care about supporting some of the obscure browsers.
keparo
+3  A: 

You can use the .complete property of the Javascript image class.

I have an application where I store a number of Image objects in an array, that will be dynamically added to the screen, and as they're loading I write updates to another div on the page. Here's a code snippet:

var gAllImages = [];

function makeThumbDivs(thumbnailsBegin, thumbnailsEnd)
{
    gAllImages = [];

    for (var i = thumbnailsBegin; i < thumbnailsEnd; i++) 
    {
        var theImage = new Image();
        theImage.src = "thumbs/" + getFilename(globals.gAllPageGUIDs[i]);
        gAllImages.push(theImage);

        setTimeout('checkForAllImagesLoaded()', 5);
        window.status="Creating thumbnail "+(i+1)+" of " + thumbnailsEnd;

        // make a new div containing that image
        makeASingleThumbDiv(globals.gAllPageGUIDs[i]);
    }
}

function checkForAllImagesLoaded()
{
    for (var i = 0; i < gAllImages.length; i++) {
        if (!gAllImages[i].complete) {
            var percentage = i * 100.0 / (gAllImages.length);
            percentage = percentage.toFixed(0).toString() + ' %';

            userMessagesController.setMessage("loading... " + percentage);
            setTimeout('checkForAllImagesLoaded()', 20);
            return;
        }
    }

    userMessagesController.setMessage(globals.defaultTitle);
}
Jon DellOro
I've used similar code in my work before. This works well in all browsers.
Gabriel Hurley
A: 

Jon DellOro has the right idea. More code, but much better overall support. Using the javascript Image class is better than the non-official onload.

agrothe