document.createElement('script')vs <script src ="">

web*_*jay 26 html javascript html5

为什么像谷歌和Facebook这样的服务使用document.createElement('script')而不仅仅是<script>

Google Analytics摘要:

<script type="text/javascript">
var gaJsHost = (("https:" == document.location.protocol) ? "https://ssl." : "http://www.");
document.write(unescape("%3Cscript src='" + gaJsHost + "google-analytics.com/ga.js' type='text/javascript'%3E%3C/script%3E"));
</script>
Run Code Online (Sandbox Code Playgroud)

可以写成:

<script src="//www.google-analytics.com/ga.js" type="text/javascript"></script>
Run Code Online (Sandbox Code Playgroud)

和Facebook的按钮一样:

<script>(function(d, s, id) {
  var js, fjs = d.getElementsByTagName(s)[0];
  if (d.getElementById(id)) return;
  js = d.createElement(s); js.id = id;
  js.src = "//connect.facebook.net/en_GB/all.js#xfbml=1&appId=xxx";
  fjs.parentNode.insertBefore(js, fjs);
}(document, 'script', 'facebook-jssdk'));</script>
Run Code Online (Sandbox Code Playgroud)

可以简化为:

<script src="//connect.facebook.net/en_GB/all.js#xfbml=1&appId=xxx"></script>
Run Code Online (Sandbox Code Playgroud)

我知道有一些安全的玩法,但除此之外,我不明白为什么我们不应该使用HTML5?

Sal*_*n A 29

在异步加载JavaScript时<script src=...>阻止浏览器document.createElement('script'); 这是主要原因.


<script src=...>从直到脚本加载并执行显示页面的其余部分标签块浏览器.这可确保脚本以正确的顺序执行,并且document.write()该脚本中的任何脚本都按预期工作.然而,这为用户创建了滞后的浏览体验.

当异步加载脚本时,浏览器可以下载脚本而不会阻止页面显示.这极大地改善了浏览体验.

要异步加载脚本,可以使用HTML标记:

<script src="..." async defer></script>
Run Code Online (Sandbox Code Playgroud)

async属性是在HTML5中引入的,而该defer属性可以作为旧版IE的后备版本添加.本文档描述了async和defer属性的工作原理.

或者,可以使用JavaScript来构建脚本标记:

var s = document.createElement('script');
s.src = "...";
document.getElementsByTagName("head")[0].appendChild(s);
Run Code Online (Sandbox Code Playgroud)

JavaScript生成的脚本标记在大多数浏览器中都有效,即使它们不了解async属性或.async = true属性.


关于无方案URI(//example.com/script.js):无方案URI似乎几乎无处不在(参见这个问题).

关于Google Analytics示例:旧代码和新代码都使用JavaScript来检测协议然后加载,http://www.或者https://ssl.通过HTML标记无法实现.