为什么像Google和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>
可以写成:
<script src="//www.google-analytics.com/ga.js" type="text/javascript"></script>
和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>
可以简化为:
<script src="//connect.facebook.net/en_GB/all.js#xfbml=1&appId=xxx"></script>
我知道其中有一些安全玩法,但除此之外我不明白为什么我们不应该使用HTML5?
答案 0 :(得分:29)
<script src=...>
阻止浏览器,而document.createElement('script')
异步加载JavaScript;这是主要原因。
<script src=...>
标记阻止浏览器显示页面的其余部分,直到加载并执行脚本为止。这可确保脚本以正确的顺序执行,并且该脚本中的任何document.write()
都可以按预期工作。然而,这为用户创造了一种滞后的浏览体验。
当异步加载脚本时,浏览器可以下载脚本而不会阻止页面显示。这极大地改善了浏览体验。
要异步加载脚本,可以使用HTML标记:
<script src="..." async defer></script>
{* 3}}属性是在HTML5中引入的,而async
属性可以作为旧版IE的后备版添加。 defer
或者,可以使用JavaScript构建脚本标记:
var s = document.createElement('script');
s.src = "...";
document.getElementsByTagName("head")[0].appendChild(s);
JavaScript生成的脚本代码在大多数浏览器中都有效,即使他们不了解async
属性或.async = true
属性。
关于无方案URI(//example.com/script.js
):无方案URI似乎几乎无处不在(This document describes how async and defer attribute work)。
关于Google Analytics示例:旧代码和新代码都使用JavaScript来检测协议,然后加载http://www.
或https://ssl.
,这是通过HTML标记无法实现的。
答案 1 :(得分:2)
除了Salman A关于延迟加载的优点之外,当静态解决方案不起作用时使用此技术。
还有其他原因。所有这些都与需要动态解决方案有关。
答案 2 :(得分:0)
是的,可以写在脚本标签中,但您引用的示例是网站为用户提供了一些代码块,他们需要在其网站上复制粘贴的内容。
所以注入更好,因为这样的网站像谷歌和Facebook
1.你可以在谷歌示例中看到,你提供它动态检测http或https
2.这样网站可以检查是否存在相同的脚本,然后选择不再像在facebook中那样再次下载。例如
3.对注入的内容有更多的控制权。因为正在注入的脚本可以动态更改,而无需用户更改正在注入的脚本的URL,这是必要的,因为许多浏览器只是将脚本保留在缓存中
这样,这些网站可以保持代码排序,不易受用户干扰