jquery中ready和和DOM的load事件
常用的文档加载方法有以下三种(两种jquery的方法):
1 2 3 4 5 6 7 8 9 $(document ).ready(function ( ) { }); $(function ( ) { }); window .load=function ( ) { };
这三种方式中,第二种是第一种的简写,可以看作一种方式,那么ready和load有何区别?
那我们看下DOM的文档加载的步骤:
解析HTML结构;
加载外部脚本和样式表文件;
解析并执行脚本代码;
构造HTML DOM模型;
加载图片等外部文件;
页面加载完毕。
在举个测试用例吧
1 2 3 4 5 6 7 $(document ).ready(function ( ) { console .log("jQuery的ready方法" ); }); window .load=function ( ) { console .log("DOM的load方法" ); }; console .log("立即执行函数" );
从以上步骤中,第三步执行的是立即执行函数,jquery的ready在第四步也就是构造HTML DOM模型的时候执行,而load在页面完全加载完之后执行。
所以可以看的出这两个方法的区别是外部资源的文件的加载上。在现在,如果为了加载几个图片,甚至用户根本没有兴趣看的图片,而让用户无限制的等待是一个非常低级的用户体验问题,所以执行在资源加载之前的代码是完全有益无害的。
我们看下jquery对ready 的实现
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 var readyList;jquery.fn.ready=function (fn ) { jQuery.ready.promise().done(fn); return this ; } jQuery.extend({ isReady: false , readyWait: 1 , holdReady: function ( hold ) { if ( hold ) { jQuery.readyWait++; } else { jQuery.ready( true ); } }, ready: function ( wait ) { if ( wait === true ? --jQuery.readyWait : jQuery.isReady ) { return ; } jQuery.isReady = true ; if ( wait !== true && --jQuery.readyWait > 0 ) { return ; } readyList.resolveWith( document , [ jQuery ] ); if ( jQuery.fn.triggerHandler ) { jQuery( document ).triggerHandler( "ready" ); jQuery( document ).off( "ready" ); } } });
上面是jQuery对ready事件的包装过程,虽然简短的几局代码,还是可以看的出来惊心动魄的过程啊。
而下面这段代码是jQuery对文档加载时机应用的处理过程
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 * ready事件的处理函数,并解除事件监听 */ function completed ( ) { document .removeEventListener( "DOMContentLoaded" , completed, false ); window .removeEventListener( "load" , completed, false ); jQuery.ready(); } jQuery.ready.promise = function ( obj ) { if ( !readyList ) { readyList = jQuery.Deferred(); if ( document .readyState === "complete" ) { setTimeout( jQuery.ready ); } else { document .addEventListener( "DOMContentLoaded" , completed, false ); window .addEventListener( "load" , completed, false ); } } return readyList.promise( obj ); }; jQuery.ready.promise(); });
DOMContentLoaded只在IE9+和现代浏览器上有,但是IE8-怎么办?jQuery作者使用document.readyState检测是否为完成状态,然后利用setTimeout触发ready函数,收益一定会在DOM ready完成之后执行, 还有一种方法 ,是通过不断使用doScoll()方法,由于DOM没有准备完成的时候运行doScoll()会报错,所以必须把doScoll放在try/catch结构中,例如:
1 2 3 4 5 6 7 try { document .documentElement.doScroll("left" ); } catch ( error ) { setTimeout( arguments .callee, 0 ); }
欢迎加入Javascript前端技术 ,群号为:85088298