Question

A webpage contains few images, 5-10, average size.

Sometimes, randomly, the loading of an image fails and it is not displayed.

Let say that every 100 images loaded 1 fails.

That may happen because the server is busy or there is a temporary network problem, any reason..

I know for sure that the request to obtain the image is valid so if I retry to load the image I have very good chances to get it.

I have code to detect when an image fails to load and trigger a callback.

But then, how can I tell the browser "retry loading that image" ?

Can I just remove the image from the DOM and put it back again?

If I append to the URL a random query string the image will be reloaded for sure but I'd prefer to avoid that because the image won't be properly cached.

I'm using jQuery, so a jQuery solution is good for me as pure JavaScript.

Was it helpful?

Solution

What you can do is just try to load the image in a new Image object. If an image loads, it will update all other places as well (similar to how if you embed the same image 50 times, once it loads once, they all show). So, in your callback (which I assume is an error callback), just try:

var img = new Image();
img.src = this.src; // this should refer to the original failed image

That'll trigger the loading of that same URL in the new image object. If it works, both will be updated and the one we just created is simply never shown anywhere.

OTHER TIPS

Inspired by samanime's suggestion, I came up with below lines of code. I call this code in jquery's document-ready event. See if it helps someone, also let me know if it requires improvements,

if (document.images) {
    var imageArray = new Array(document.images.length);
    var i = 0;
    for (i = 0; i < document.images.length; i++) {
        $(document.images[i]).attr('dt-retry', 3);
        imageArray[i] = new Image();
        imageArray[i].src = document.images[i].src;
        //try to reload image in case of error
        //retry for 3 times
        var imgErrorFunction = function () {
            try {
                var img = this;
                var isRet = true;
                var r = 3;
                if (img.hasAttribute('dt-retry')) {
                    r = parseInt(img.getAttribute('dt-retry'));
                    r = r - 1;
                    img.setAttribute('dt-retry', r);
                    if (r <= 0) {
                        isRet = false;
                    }
                }

                if (isRet) {
                    var temp = new Image();
                    temp.setAttribute('dt-retry', r);
                    temp.onerror = imgErrorFunction;
                    temp.src = img.src;
                }
            } catch (e) {

            }
        }

        document.images[i].onerror = imgErrorFunction;
    }
}

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top