不拥抱doucment.write

Posted daidaidai

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了不拥抱doucment.write相关的知识,希望对你有一定的参考价值。

document.write的名声好像一直不是很好,也许是它经常出现在初学者教程中,也可能是被劫持的js文件中经常用出现这东西,导致大家都满排斥它的。
但是,无论它的长相多难看,它确实能解决同步加载的问题,比如创建一个script,然后把它appendChild到head中

//x.js
alert(1)
 <script>
    let $scp = document.createElement(‘script‘)
    $scp.src = ‘./x.js‘
    document.querySelector(‘head‘).appendChild($scp)
  </script>
  <script>
    alert(2)
  </script>

输出的消息先是2然后是1,程序并不会因为appendChild而陷入等待

接下来使用document.write在页面中塞入一个script

<script>
    document.write(`<script src="./x.js"></script>`)
  </script>
  <script>
    alert(2)
  </script>

发现程序按理想的顺序执行了,document.write会使程序陷入等待,输出的消息先是1然后是2

要注意的是,如果塞入的script是跨站的,在chrome中会出现下面的警告

<script>
    //a.com
    document.write(`<script src="//b.com/x.js"></script>`)
  </script>

 技术分享图片

就是说,在网络很差的情况下,document.write写入的script如果是跨站的会被无视掉的!

 

利用它同步加载资源特性就能解决一些场景下的问题

比如需要按照平台相关的代码来同步引入代码

<script>
    const ua = navigator.userAgent
    if(/android_ysdk/.test(ua)){
      document.write(`<script src="./x.js"></script>`)
    }
    if(/MicroMessagenger/.test(ua)){
      document.write(`<script src="./weixin.js"></script>`)
    }
  </script>

还有为了按需加载那些不支持某些特性浏览器的polyfill,需要做兼容检测处理

<script>
    if(!Object.keys){
      document.write(`<script src="./object-keys.js"></script>`)
    }
    if(!Array.isArray){
      document.write(`<script src="./array-isArray.js"></script>`)
    }
  </script>

document.write能够想到的用途就上面这儿了,总之就是为了解决同步资源加载问题

上面的两种实现方式都有能够替代的方案:

需要插入代码的检测逻辑服务器来判断

平台相关的代码由服务器端检测ua来输入script到html

polyfill的代码同样也是由服务器获取到ua,再根据一个浏览器特性支持列表来决定加载哪些polyfill。如果需要加载,那么往页面中输入script

polyfill打包到bundle里面

在各类构建工具配置中,可以把需要的polyfill打包到bundle中,不建议在开发js中import全部polyfill,这会导致最终文件体积过大。通常会把需要用到的polyfill按需写到配置里的plugins中

打包多个页面

针对需要在多个环境下存在的页面可以构建出多个,可根据不同环境给到页面。也可打包出一个通用的页面,根据当前的环境跳到具体的页面

 

document.write的退出是个趋势,我们应该积极使用其他的方案解决,减少使用document.write

 

以上是关于不拥抱doucment.write的主要内容,如果未能解决你的问题,请参考以下文章

如何从拥抱脸下载模型?

拥抱自动化,CODING 2.0 持续集成全新上线

StackView 不拉伸,拥抱内容

苹果拥抱 Rust,正在将 C 代码移植到 Rust

刷新片段不再起作用?

UICollectionViewCompositionalLayout 水平,使用估计和不水平拥抱时不计算内容的宽度