Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

JavaScript: how to retry loading an image without appending query string?

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.

like image 535
Paolo Avatar asked Dec 06 '22 02:12

Paolo


2 Answers

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.

like image 184
samanime Avatar answered Jan 17 '23 18:01

samanime


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;
    }
}
like image 38
pgcan Avatar answered Jan 17 '23 20:01

pgcan