Reyedy
Reyedy

Reputation: 918

Restart gif without reloading it in IE11

I'm trying to make a gif restart when the user clicks on it, without having to reload it (my gif is too heavy for that, I actually preload it for my application). My current code works perfectly on Chrome and all "modern browsers", but I need that to work in IE11 as well, and that's where the struggle begins.

Here is a sample code, that works perfectly on Chrome but not on IE11:

function activate_gif(){
    document.getElementById("img1").src = "https://i.imgur.com/Rsc0qOw.gif";
}
.myDiv{
  width: 500px;
  height: 300px;
}

.myDiv img{
  width: 100%;
  height: 100%;
}
<button onclick="activate_gif()">
  Click me
</button>
<div class="myDiv">
  <img id="img1" src="https://i.imgur.com/Rsc0qOw.gif">
</div>

You can also find it on this jsFiddle: https://jsfiddle.net/c6hodyh2/3/

You can find an other (not) working example of the problem (perfect with Chrome, not working with IE): https://codepen.io/InSightGraphics/pen/CAlci

What I've tried so far

Attempt 1

From this SO question, I tried the following JS code, to "force" the cache to refresh:

function activate_gif(){
    document.getElementById("img1").src = "";
    document.getElementById("img1").src = "https://i.imgur.com/Rsc0qOw.gif";
}

Result: No success, it had absolutely no different effect from my original code.

Attempt 2

From this article, I tried to refresh the innerHTML content:

function activate_gif(){
    document.getElementById("img1").style.display = '';
    document.getElementById("img1").innerHTML = document.getElementById("img1").innerHTML;
}

Result: No change in IE, and it stopped working in the other browsers, so I suppose it triggered a console error.

Attempt 3

From this SO question, I tried to use a simplified version of the solution, basically by forcing the image to be loaded again by adding a random suffix to its source URL:

function activate_gif(){
    document.getElementById('myImg').src = 'mysrc.gif?' + Math.random();
}

Result: This reloads the gif, which solves the cache problem by itself. However, the gifs I use in my real-life application are too heavy, so if the image is to be downloaded everytime the user presses the button, it results in a poor user experience, especially for those with a weaker bandwidth.

Attempt 4

From @IStepashka's answer, I tried to first set a (random and found on the web) blank image before setting back my original source:

function activate_gif(){
    document.getElementById("img1").src = "https://i.ytimg.com/vi/f3cLOucMpD0/maxresdefault.jpg";
    document.getElementById("img1").src = "https://i.imgur.com/Rsc0qOw.gif";
}

Result: Same as attempt 1, it didn't change anything. My code is still working on Chrome, but not on IE.

Upvotes: 4

Views: 905

Answers (3)

Lionia Vasilev
Lionia Vasilev

Reputation: 12748

It might be more appropriate to convert GIF file to a video and use <video> HTML tag. See Replace Animated GIFs with Video article by Jeremy Wagner. But if you want to stick to GIF you can utilize XMLHttpRequest, Blob and object URL given CORS and cache related HTTP headers are appropriately configured:

function activate_gif(){
    var url = "https://i.imgur.com/Rsc0qOw.gif";
    var img = document.getElementById( "img1" );

    var xhr = new XMLHttpRequest();
    // Browser will take cached response if it has cache entry with url key.
    xhr.open( "GET", url );
    xhr.responseType = "blob";
    xhr.onload = function() {
        if ( xhr.status != 200 ) {
            // Complain.
            return;
        }
        var blobUrl = URL.createObjectURL( xhr.response );
        img.src = blobUrl;
        setTimeout( function () {
            // Let browser display blob and revoke blob after stack unwind.
            URL.revokeObjectURL( blobUrl );
        }, 0 ); // You might need to increase delay time for large images.
    };
    xhr.send();
}
.myDiv{
  width: 500px;
  height: 300px;
}

.myDiv img{
  width: 100%;
  height: 100%;
}
<button onclick="activate_gif()">
  Click me
</button>
<div class="myDiv">
  <img id="img1" src="https://i.imgur.com/Rsc0qOw.gif">
</div>

You can also use browser detection to use more efficient and simpler code in other user agents.

For more information check:

Upvotes: 2

Boris
Boris

Reputation: 1191

It seems that IE 11 will not actually replay a (non-looping) gif, if it has it in cache, and all instances of a same-src gif are actually synchronized… It seems like another of IE's... Erm, let's call them quirks.

Here is a (sad) workaround. It does reload the gif, but at least it pre-reloads it in the background so as to not have too much of an impact on user xp. I changed your gif to a 2MO+ one to show the background loading.

Please note that this should be only used on IE, since other browser work well with the simple solution.

var oldNode = document.getElementById("img1"),
    src = oldNode.src + "?bust=",
    nextNode = oldNode.cloneNode(),
    parent = oldNode.parentNode;
nextNode.src = src + new Date().getTime();
function activate_gifIE(){
  oldNode.removeNode();
  parent.appendChild(nextNode);
  oldNode = nextNode;
  nextNode = oldNode.cloneNode();
  
  nextNode.src = src + new Date().getTime();
}
.myDiv{
  width: 500px;
  height: 300px;
}

.myDiv img{
  width: 100%;
  height: 100%;
}
<button onclick="activate_gifIE()">
  Click me
</button>
<div class="myDiv">
  <img id="img1" src="https://media.giphy.com/media/LRVnPYqM8DLag/giphy.gif" height="200px">
</div>

I have seen workarounds such as this one and that one, but they involve looping gifs, and overlaying a still frame in front of them, or replacing them with it. Also on IE 11, you would have to settle for the user landing at a random time in the gif, because you can't seem to get it to replay…

Anyway, hope it helps.

Upvotes: 0

iStepashka
iStepashka

Reputation: 302

Try to first set any blank image to source and the get back your original source image. like that:

function activate_gif(){
    document.getElementById("img1").src = "images/blank.jpg"     
    document.getElementById("img1").src = "https://i.imgur.com/Rsc0qOw.gif";

}

Upvotes: 0

Related Questions