JavaScript中有没有一种方法可以在解析HTML时在浏览器加载图像之前更改图像路径

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

本文关键字:图像 加载 浏览器 HTML 路径 一种 方法 JavaScript 有没有      更新时间:2023-09-26

我正在使用IE Edge的模拟器模式来测试一些工作,其中一个项目需要IE8。模拟器对于调试一些原始IE8在黑盒方面做得很好的东西非常有用。我正试图找到一种方法来解决这个错误,因为微软不愿意修复它

问题是IE8模拟器在加载SVG图像时挂起。我目前正在使用这个SVG回退库,它在真正的IE8上运行得很好,但我想知道是否有一种方法可以在解析HTML时尝试加载SVG图像之前,使用Javascript修改事件对象原型以更改浏览器的行为?有没有这样的方法来解决这个问题,或者我应该接受这个bug?我有一个肮脏的变通方法,它确实奏效了,但我希望找到一个更积极主动的解决方案。

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);

没有错误,图像只是停留在"未初始化"状态(因此我无法使用onerror事件)。我也不知道我可以使用任何onbeforeoload事件。

使用间隔是唯一的解决方案吗?

编辑

我意识到没有完美的解决方案,但要解决基本的<img>backgroundImage风格,使用interval似乎可以很好地解决性能问题。除此之外,回退图像的加载速度似乎更快。我更新了我的SVG回退以使用interval,而不是使用onload事件来解决IE8模拟器和实际IE8。

这是一个非常奇怪的错误,因为Edge中没有旧版本的模拟模式,只有移动模式和用户代理字符串模拟,这只会允许您"调试由浏览器嗅探引起的错误",但与某些不支持的功能无关。

使用回退是众多选项中的一种,但没有"干净"的方法可以做到这一点。除此之外,它不会使用<object><iframe><embded>元素或内联<svg>元素来求解SVG图像。

因此,这并没有直接指向您的问题,IE团队应该解决这个问题,因为这是他们浏览器中的一个错误,但只是为了破解,这里有一种方法可以在获取原始图像之前更改图像的src。

免责声明

再一次,这是一个黑客攻击,不应该在任何生产或开发网站上使用 也许只是用于像您这样的边缘调试案例和实验,但仅此而已

注意:这将适用于现代浏览器,包括带有IE8用户字符串仿真集的Edge,但在原始IE8中不适用。


转储前

应该在文档的<head>中调用此代码,最好是在最上面调用,因为在此之前调用的所有代码都将被调用两次。

阅读评论。

<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>

还有一个无法使用IE8 UA字符串的实际示例,因为plnkr.co不允许在他的网站上使用此浏览器:-/