最近两天不忙的时候再回过来研究一下jquery的源码,看到$(document).ready()时,深入的研究了一下dom的加载问题。

我们都知道,window.onload可以解决我们的js执行时机问题。有了它,可以把代码放在页面的任何位置。但是我们也知道,window.onload 要在html、css、js、img全部加载完后才会触发,而这样会影响页面的访问速度。因此,jquery通过封装$(function)做到了DOM加载完毕时就对js内容进行触发。

那jquery做到的原理是什么呢?我从原理上简单的做一下分析。

在IE9+、chorme、firefox等现代浏览器中,有个原生的js事件:DOMContentLoaded  当这个事件触发时,就说明DOM已经加载完毕,可以进行下面的js操作了

document.addEventListener('DOMContentLoaded',function(){alert(123);},false);

但是IE8以下是不支持这个事件的,所以IE用的是onreadystatechange事件

document.onreadystatechange = function(){
if(document.readyState == 'complete'){
alert('Dom已经加载完毕')
}
}

但是,非标准浏览器不会这么容易让我们好过。

首先,当document.readyState == 'complete'时,图片等文件已经加载完成了,虽然会在window.onload 之前执行,但是对交互效果来说还是触发的太晚了。有些站点的图片要下载下来是很慢很慢滴!

我在这里随便举个例子:

<body>
<div>12345555555555555555555555555</div>
<img src="http://b.hiphotos.baidu.com/zhidao/pic/item/c8177f3e6709c93da9f2dafa9b3df8dcd10054bf.jpg" alt=""> <script> alert(111)
window.onload = function(){
alert(456)
}
document.onreadystatechange = function(){
if(document.readyState == 'complete'){
alert(123);
//complete是指所有资源包括图片js等文件全部加载完成后才会触发。
//readyState == 'complete'确实会在onload前触发,但是还是触发的太晚。
}
} </script>
</body>

大家看,在IE8下,当页面执行时,首先弹出111,这毫无疑问。然后呢?对不起,是图片在页面中完全显示出来。然后再弹出123,最后弹出456.

再次,alert(123)执行时机也不确定,因为同一段代码,再IE7中,或者更高层的IE9种,有时图片还没有加载下来,alert(123)执行了。所以单纯使用这个readyState不太靠谱

那么jquery中是如何做的呢?jquery中用了一个IE才能识别的属性:document.documentElement.doScroll

这是个什么东东?好像从来没有见过? 这就是学习源码的好处,可以看看大师级人物是如何做处理的,并且我们可以从中取其精华,好不惬意!

兼容不支持该事件的浏览器

在IE8中,可以使用readystatechange事件来检测DOM文档是否加载完毕.在更早的IE版本中,可以通过每隔一段时间执行一次document.documentElement.doScroll("left")来检测这一状态,因为这条代码在DOM加载完毕之前执行时会抛出错误(throw an error)。

doScroll通过时readyState可能为interactive, 也可能为complete. 但是一定会在DOM结构稳定后, 图片加载完毕前执行.

// The DOM ready check for Internet Explorer
function doScrollCheck() {
if ( jQuery.isReady ) {
return;
} try {
// If IE is used, use the trick by Diego Perini
// http://javascript.nwbox.com/IEContentLoaded/
document.documentElement.doScroll("left");
} catch(e) {
setTimeout( doScrollCheck, 1 );
return;
} // and execute any waiting functions
jQuery.ready();
}

这是jquery的源码,通过异常捕获,如果DOM没有加载完,则会一直catch这个setTimeout ,直到dom加载完,执行以下try里面的doScroll

具体doScroll的详细含义大家可以从网上查查,我这里就不列举了

MSDN 关于 JScript 的一个方法有段不起眼的话,当页面 DOM 未加载完成时,调用 doScroll 方法时,会产生异常。那么我们反过来用,如果不异常,那么就是页面DOM加载完毕了!

当然,doScroll的运用前提是页面中没有iframe,如果有iframe,那么只能是图片之类的全加载完毕才执行了。

从jQuery源码阅读看 dom load的更多相关文章

  1. jquery源码阅读(1)

    每天坚持阅读一定量的的jquery代码,积少成多!加油加油! jquery-2.2.1的9161~9194行 1 if ( typeof define === "function" ...

  2. JQuery源码阅读记录

    新建html文件,在浏览器中打开文件,在控制台输入consoole.log(window);新建html文件,引入JQuery后在浏览器中打开,在控制台同样输入consoole.log(window) ...

  3. jquery源码阅读笔记一

    1. jquery无new的构造函数. 无new的构造函数是怎么实现的.比如我们一般这么用jQuery. $(".test").text(); 但是我们一般是这么写的. var t ...

  4. jQuery源码分析系列

    声明:本文为原创文章,如需转载,请注明来源并保留原文链接Aaron,谢谢! 版本截止到2013.8.24 jQuery官方发布最新的的2.0.3为准 附上每一章的源码注释分析 :https://git ...

  5. [转]jQuery源码分析系列

    文章转自:jQuery源码分析系列-Aaron 版本截止到2013.8.24 jQuery官方发布最新的的2.0.3为准 附上每一章的源码注释分析 :https://github.com/JsAaro ...

  6. jQuery源码分析系列(转载来源Aaron.)

    声明:非本文原创文章,转载来源原文链接Aaron. 版本截止到2013.8.24 jQuery官方发布最新的的2.0.3为准 附上每一章的源码注释分析 :https://github.com/JsAa ...

  7. jQuery源码分析系列——来自Aaron

    jQuery源码分析系列——来自Aaron 转载地址:http://www.cnblogs.com/aaronjs/p/3279314.html 版本截止到2013.8.24 jQuery官方发布最新 ...

  8. jquery源码分析学习地址

    http://www.ccvita.com/121.htmljQuery工作原理解析以及源代码示例http://www.cnblogs.com/haogj/archive/2010/04/19/171 ...

  9. jquery 源码分析学习地址

    http://www.ccvita.com/121.htmljQuery工作原理解析以及源代码示例http://www.cnblogs.com/haogj/archive/2010/04/19/171 ...

随机推荐

  1. memcache命中统计

    把memcache.php放在可以访问的位置,默认账户admin,密码admin 参考http://a.linji.cn/2011/12/memcachedphp.txt http://linji.c ...

  2. Meta http-equiv的属性详解 来自wanglehui

    Meta http-equiv 语法标签格式:<meta http-equiv="参数" content="参数值"> 1."过期时间&q ...

  3. MVCC PostgreSQL实现事务和多版本并发控制的精华

    原创文章,同步发自作者个人博客,http://www.jasongj.com/sql/mvcc/ PostgreSQL针对ACID的实现机制 事务的实现原理可以解读为RDBMS采取何种技术确保事务的A ...

  4. js中的break ,continue, return (转)

    面向对象编程语法中我们会碰到break ,continue, return这三个常用的关键字,那么关于这三个关键字的使用具体的操作是什么呢?我们在使用这三关键字的时候需要注意和需要理解的规则是什么呢? ...

  5. 新冲刺Sprint3(第七天)

    一.Sprint介绍 商家功能模块持续更新着...... 二.Sprint周期 看板: 燃尽图:

  6. cache缓存帮助类

    public class CacheHelper { /// <summary> /// 创建缓存项的文件 /// </summary> /// <param name= ...

  7. Mongodb优化

    本文将从各个层面讲述Mongodb的优化方法

  8. 每天一个命令ls 2015/4/1

    ls命令可以说是Linux下最常用的命令 -a 列出目录下的所有文件,包括以 . 开头的隐含文件.-b 把文件名中不可输出的字符用反斜杠加字符编号(就象在C语言里一样)的形式列出.-c 输出文件的 i ...

  9. jdb调试命令

    常用调试命令: run GeoHashTest #带参数运行 stop at GeoHashTest:22 #断点GeoHashTest文件的22行 stop in GeoHashEncode.Enc ...

  10. cat /proc/devices 和ls /dev

    对于新手来讲,linux的框架实在是太庞大,况且很多知识点需自己做才能理解 设备 文件 ,设备编号  #ll  -a /dev  在每一行都可以看到设备文件.设备编号(主.次) 对于每种硬件设备,系统 ...