Open
Description
js动态添加script
标签
(function(){
var scriptEle = document.createElement("script");
scriptEle.type = "text/javasctipt";
scriptEle.async = true;
scriptEle.src = "http://cdn.bootcss.com/jquery/3.0.0-beta1/jquery.min.js";
var x = document.getElementsByTagName("head")[0];
x.insertBefore(scriptEle, x.firstChild);
})();
但是这种加载方式执行完之前会阻止onload事件的触发
,而现在很多页面的代码都在onload时还执行额外的渲染工作,所以还是会阻塞部分页面的初始化处理。
注意:
页面加载完成有两种事件:
- ready事件:表示文档结构(DOM结构)已经加载完成(不包含图片等非文字媒体文件),
- onload事件:指示页面包含图片等文件在内的所有元素都加载完成。(可以说:ready 在onload 前加载)
onload时的异步加载
(function(){
if(window.attachEvent){
window.attachEvent("load", asyncLoad);
}else{
window.addEventListener("load", asyncLoad);
}
var asyncLoad = function(){
var ga = document.createElement('script');
ga.type = 'text/javascript';
ga.async = true;
ga.src = ('https:' == document.location.protocol ? 'https://ssl' : 'http://www') + '.google-analytics.com/ga.js';
var s = document.getElementsByTagName('script')[0];
s.parentNode.insertBefore(ga, s);
}
})();
这种方法只是把插入script的方法放在一个函数里面,然后放在window的onload方法里面执行,这样就解决了阻塞onload事件触发的问题。
注: DOMContentLoaded
与load
的区别。前者是在document已经解析完成,页面中的dom元素可用,但是页面中的图片,视频,音频等资源未加载完,DOMContentLoaded
作用同jQuery中的ready
事件;后者的区别在于页面所有资源全部加载完毕。
$(document).ready()
需要引入jquery,兼容所有浏览器
$(document).ready(function() {
alert("加载完成!");
});
<script>标签的async="async"属性
- async属性规定一旦脚本可用,则会异步执行
- async属性仅适用于外部脚本
- 此方法不能保证脚本按顺序执行
- 他们将在onload事件之前完成
- async一旦下载完,渲染引擎就会中断渲染,执行这个脚本以后,再继续渲染。
<script type="text/javascript" src="xxx.js" async="async"></script>
对于async标记,浏览器的解析过程是这样的:
- 浏览器开始解析HTML网页
- 解析过程中,发现带有async属性的script标签
- 浏览器继续往下解析HTML网页,同时并行下载script标签中的外部脚本
- 脚本下载完成,浏览器暂停解析HTML网页,开始执行下载的脚本
- 脚本执行完毕,浏览器恢复解析HTML网页
<script>标签的defer="defer"属性
- defer要等到整个页面在内存中正常渲染结束,才会执行。
- 兼容所有浏览器
- 此方法可以确保所有设置了defer属性的脚本按顺序执行
<script type="text/javascript" defer></script>
对于defer标记,浏览器的解析过程是这样的:
- 浏览器开始解析HTML网页
- 解析过程中,发现带有defer属性的script标签
- 浏览器继续往下解析HTML网页,同时并行下载script标签中的外部脚本
- 浏览器完成解析HTML网页,此时再执行下载的脚本
es6模块type="module"属性
浏览器对于带有type=”module”
的<script>
,都是异步加载,不会造成堵塞浏览器,即等到整个页面渲染完,再执行模块脚本,等同于打开了<script>标签的defer属性 。如下:
<script type="module" src="XXX.js"></script>
ready()与onload()的区别
window.onload()(不推荐)
- 加载时机: 必须等待网页全部加载完毕(包括图片等),然后再执行JS代码。
- 执行次数: 只能执行一次,如果第二次,那么第一次的执行会被覆盖。
- 简写: 无。
举例:
window.onload = function() { console.log("text1");};
window.onload = function() { console.log("text2");};
// ƒ () { console.log("text2");} // 结果只输出第二个
$(document).ready()
- 加载时机: 只需要等待网页中的DOM结构加载完毕,就能执行JS代码。
- 执行次数: 可以执行多次,不会覆盖上一次。
- 简写:
$(function () {})
。
举例:
$(document).ready(function(){console.log("Hello")});
$(document).ready(function(){console.log("Hello")});
// Hello
// Hello
注意
async
和defer
这两个属性只是script标签在header标签
中使用的,如果你把它放在body后面是无效的