为什么使用document.write不能重载多个defer脚本?

作者站长头像
站长
· 阅读数 14
<!DOCTYPE html>
<html lang="en">
  <head>
    <meta charset="UTF-8" />
    <meta name="viewport" content="width=device-width, initial-scale=1.0" />
    <title>demo</title>
  </head>
  <body>
    <script>
      const handError = (srcEle, num = 1) => {
        console.log(srcEle.src, ' is error');
        const url = new URL(srcEle.src);
        const newUrl = 'test' + srcEle.src.split('/').pop();
        const newSrciptStr = `<script src=${newUrl} onerror="handError(this)" onload="handLoad(this)"><\/script>`;
        document.write(newSrciptStr);
        // const scriptObj = document.createElement('script');
        // scriptObj.src = newUrl;
        // scriptObj.setAttribute('onerror', 'handError(this)');
        // scriptObj.setAttribute('onload', 'handLoad(this)');
        // document.body.appendChild(scriptObj);
      };
      const handLoad = (srcEle) => {
        console.log(srcEle.src, ' is loaded');
      };
      window.addEventListener('DOMContentLoaded', () => {
        console.log('DOMContentLoad');
      });
    </script>
    <div>demo</div>
    <script defer src="./1.js" onerror="handError(this)" onload="handLoad(this)"></script>
    <script defer src="./2.js" onerror="handError(this)" onload="handLoad(this)"></script>
    <script defer src="./3.js" onerror="handError(this)" onload="handLoad(this)"></script>
  </body>
</html>

为什么使用doeument.write不能重载异步脚本2.js和3.js,而使用appendChild能全部重载。图3为注释write使用appendChild的结果,图4为删除defer属性后使用write能够正常重载。为什么使用document.write不能重载多个defer脚本?为什么使用document.write不能重载多个defer脚本?为什么使用document.write不能重载多个defer脚本?为什么使用document.write不能重载多个defer脚本?目前估计产生问题的原因在:defer属性的异步加载脚本与DOMContentLoaded以及document.write的这三者之间有某种连系,导致在第一次写入脚本后,覆盖了页面,并一直处于DOMContentLoaded前的状态。具体是什么原因导致的,希望大神们能解惑。

回复
1个回答
avatar
test
2024-09-07

异步加载的脚本会在docuemnt的readyState属性变成了interactive后执行,但此时文档流已经关闭了,在使用write进行写入就会默认执行document.open()打开新的文档流进行写入,所以会覆盖页面。并且在执行write后,没有调用document.close()关闭文档流,所以浏览器会一直处于解析状态,即DOMContentLoaded之前。

回复
likes
适合作为回答的
  • 经过验证的有效解决办法
  • 自己的经验指引,对解决问题有帮助
  • 遵循 Markdown 语法排版,代码语义正确
不该作为回答的
  • 询问内容细节或回复楼层
  • 与题目无关的内容
  • “赞”“顶”“同问”“看手册”“解决了没”等毫无意义的内容