Nicolas Bouvrette Nicolas Bouvrette - 4 years ago 106
HTML Question

Is there a way in JavaScript to change image path before the browser loads them when parsing HTML?

I'm using IE Edge's emulator mode to test some work and one of the project I work on requires IE8. The emulator is pretty useful to debug some stuff that the original IE8 is doing a good job at blackboxing. I'm trying to find a way around this bug since Microsoft isn't willing to fix it.

The problem is that IE8 emulator hangs on SVG image load. I'm currently using this SVG fallback library which works great on the real IE8 but I was wondering if there is a way to modify events or object prototypes using Javascript to change the behavior of the browsers before it tries to load SVG images when parsing HTML? Is there such a way to solve this issue or should I just live with this bug? I have this dirty workaround which does the trick but I'm hoping to find a more proactive solution.

var fixMySVG = setInterval(function () {
var elements = document.getElementsByTagName('img');
for (var i = 0; i < elements.length; i++) {
var element = elements[i];
element.src = element.src.replace(/^(.+)(\.svg)(\?.)*$/ig, '$1.' + 'png' + '$3');
}
if (document.readyState == 'complete') {
clearInterval(fixMySVG);
}
}, 100);


There is no error, the image is just stuck in an 'uninitialized' state (so I cannot use the
onerror
event). I'm also unaware of any
onbeforeoload
event I could use.

Is using interval the only solution?

Edit

I realize there is no perfect solution but to solve basic and
backgroundImage
style, using interval seems to do an good job without performance hit. On top of that fall back images seems to load faster. I updated my SVG fallback to use interval instead of using
onload
events which solve both IE8 emulator and the real IE8.

Answer Source

It's a really odd bug, since there is no older-version emulation mode in Edge, just mobile one and user-agent string emulation, which will just allow you "to debug errors caused by browser sniffing", but in no way it is related to some feature non-support.

So this doesn't point directly to your issue, which should be fixed by IE team since it's a bug in their browser, but just for the hack, here is a way to change the src of an image before the fetching of the original one starts.

Disclaimer

Once again, this is a hack and should not be used in any production nor development site maybe just for an edge debugging case like yours and for experimentation but that's all !

Note : this will work in modern browsers, including Edge with IE8 user-string Emulation set, but not in the original IE8.


Before the dump

This code should be called in the <head> of your document, preferably at the top-most, since everything that is called before it will be called twice.

Read the comments.

<script id="replaceSrcBeforeLoading">
  // We need to set an id to the script tag
  // This way we can avoid executing it in a loop
  (function replaceSrcBeforeLoading(oldSrc, newSrc) {
    // first stop the loading of the document
    if ('stop' in window) window.stop();
    // IE didn't implemented window.stop();
    else if ('execCommand' in document) document.execCommand("Stop");
    // clear the document
    document.removeChild(document.documentElement);

    // the function to rewrite our actual page from the xhr response
    var parseResp = function(resp) {
      // create a new HTML doc
      var doc = document.implementation.createHTMLDocument(document.title);
      // set its innerHTML to the response
      doc.documentElement.innerHTML = resp;
      // search for the image you want to modify
      // you may need to tweak it to search for multiple images, or even other elements
      var img = doc.documentElement.querySelector('img[src*="' + oldSrc + '"]');
      // change its src
      img.src = newSrc;
      // remove this script so it's not executed in a loop
      var thisScript = doc.getElementById('replaceSrcBeforeLoading');
      thisScript.parentNode.removeChild(thisScript);
      // clone the fetched document
      var clone = doc.documentElement.cloneNode(true);
      // append it to the original one
      document.appendChild(clone);
      // search for all script elements
      // we need to create new script element in order to get them executed
      var scripts = Array.prototype.slice.call(clone.querySelectorAll('script'));

      for (var i = 0; i < scripts.length; i++) {
        var old = scripts[i];
        var script = document.createElement('script');
        if (old.src) {
          script.src = old.src;
        }
        if (old.innerHTML) {
          script.innerHTML = old.innerHTML;
        }
        old.parentNode.replaceChild(script, old);
      }
    }

    // the request to fetch our current doc
    var xhr = new XMLHttpRequest();
    xhr.onreadystatechange = function() {
      if (this.readyState == 4 && (this.status == 200 || this.status == 0)) {
        var resp = this.responseText || this.response;
        parseResp(resp);
      }
    };
    xhr.open('GET', location.href);
    xhr.send();
  })('oldSrc.svg',
    'newSrc.svg');
</script>

And a live example which won't work with the IE8 UA string since plnkr.co just doesn't allow this browser on his website :-/

Recommended from our users: Dynamic Network Monitoring from WhatsUp Gold from IPSwitch. Free Download