页面加载状态
$(document).ready()
$(function(){})
这两个是我们在页面初始化时经常使用的监听方案,那么他的实际的执行关系时什么样的呢?在原生js中是什么样的一种表现?
以下我会一而再再而三的写DOMContentLoaded,因为好多同学都没有怎么听说过这个事件
onload vs DOMContentLoaded
定义
onload:
当onload事件触发的时候,页面上的所有dom,样式表,脚本,图片,flash都已经加载完成了
DOMContentLoaded:
当DOMContentLoaded事件触发时,仅当dom加载完成,不包括样式表,图片,flash
光看定义,一目了然,哪个比较适合作为我们判断的标准:图片啊什么的,我们完全可以不用等。
DOMContentLoaded事件详细研究
DOMContentLoaded边界事件
外链样式在某些浏览器下面会影响脚本的加载。
在某些Gecko和Webkit引擎版本的浏览器里面,&&IE8在内,会同时发起多个http的请求并行加载样式表和脚步,但是脚本会等样式表加载完成之后才会被执行,甚至样式表加载之前页面都不会渲染。opera不会,样式表未加载好就可以执行js。
DOMContentLoaded兼容性
DOMContentLoaded事件兼容处理方案
由上可知,DOMContentLoaded事件在ie9以下是不支持的,那么惯例,我们要开始搞兼容处理方案
ie8及以下兼容处理方案
ie的一般处理方案
html加载过程中会有一个document.readyState状态
五种状态:
0(未初始化):还没有send
1 loading(载入):正在发送请求
2 loaded(载入完成):执行完成,已经接收到全部响应内容
3 interactive(交互): 正在解析响应内容
4 complete(完成): 响应内容解析完成,客户端可以用了。
complete事件和window.onload事件是同时的。
这就是要监听页面的readystatechange事件,当事件为interactive||complete时就可以开始做js的事情了。
带iframe的处理
但是当页面中带有iframe时,这个readyState状态会挂起一直等待,等待页面的iframe也加载完毕之后再处理,这个过程是我们不想要得,那就有另外一种处理方案
(function doScrollCheck(){
try{
temp.doScroll('left');
result += 'ie scroll' + (new Date()).getTime()+'\n';
} catch(e){
return setTimeout(doScrollCheck, 50);
}
}());
doScroll事件在页面加载完成之前是不能调用的,调用就失败了,可以用try catch的方法来完成
jQuery处理方案
基本上说清楚了,那么我们来看看jQuery是怎么搞的吧
jQuery.ready.promise = function( obj ) {
if ( !readyList ) {
readyList = jQuery.Deferred();
//如果执行到此处时,document.readyState已经是complete,就可以是ready了
if ( document.readyState === "complete" ) {
setTimeout( jQuery.ready );
//标准处理方案,DOMContentLoaded,一般浏览器都有的。
} else if ( document.addEventListener ) {
//事件监听
document.addEventListener( "DOMContentLoaded", DOMContentLoaded, false );
// 做个备份,不管怎么样,load事件时一定一定会执行的
window.addEventListener( "load", jQuery.ready, false );
// ie处理方案
} else {
//这个时间比doscroll事件快好多,他会在交互状态就触发,见demo2
document.attachEvent( "onreadystatechange", DOMContentLoaded );
// 还是备份
window.attachEvent( "onload", jQuery.ready );
// 且没有iframe的方案
var top = false;
try {
top = window.frameElement == null && document.documentElement;
} catch(e) {}
if ( top && top.doScroll ) {
(function doScrollCheck() {
if ( !jQuery.isReady ) {
try {
top.doScroll("left");
} catch(e) {
return setTimeout( doScrollCheck, 50 );
}
jQuery.ready();
}
})();
}
}
}
return readyList.promise( obj );
};
这就是我们常用的ready事件
敬请期待下期,defer sync 各种各种和loaded DOMContentLoaded事件的关系