请选择 进入手机版 | 继续访问电脑版
收藏本站腾讯微博新浪微博
点点网模板设计大赛 phpchina

经典论坛

 找回密码
 注册

QQ登录

只需一步,快速开始

蓝色理想 最新研发动态 用悬赏 三天解决问题 解决访问速度慢 论坛支持农历生日 - 给官方提建议

论坛活动及任务 归纳网站最新活动 地图任务 邮件更新任务:保护帐号安全

积分换实物,来参加蓝色理想积分兑换吧! 联系招聘客服 蓝色理想帮你找工作! 万元奖励等你拿——点点网模板设计大赛

查看: 4465|回复: 12

Dom加载 [复制链接]

zidanezhicong 楼主

我爱阿仙奴

银牌会员 手机认证 

帖子
571
体力
2056
威望
1
居住地
广东省 深圳市
发表于 2008-5-8 01:05:45 |显示全部楼层
当大家使用window.onload执行一个函数时,必须要等到页面上的图片等信息全部加载完毕之后才执行的。但很多时候图片的数量比较多,所以需要很多时间下载。更令人尴尬的是,当网页文档(或者说Dom)已经加载完毕,而图片尚未加载完毕,很多用户已经开始浏览网页,但这时很多由window.onload所触发的函数不能执行,这就导致一部分功能不能完美地给用户使用,更严重的是会给用户留下不好的印象!

现在,我们来研究一下如何解决这个问题,解决方法就是在DOM加载完毕之后就执行程序。

先介绍两个人。一,jquery的作者:John Resig;二,javascript的世界级大师:dean edwards。(大家要记住这两位天才!)

jquery里有专门解决DOM加载的函数$(document).ready()(简写就是$(fn)),非常好用!John Resig在《Pro JavaScript Techniques》里,有这样一个方法处理DOM加载,原理就是通过document&& document.getElementsByTagName &&document.getElementById&& document.body 去判断Dom树是否加载完毕。代码如下:
  1. function domReady( f ) {
  2. // 如果DOM加载完毕,马上执行函数
  3. if ( domReady.done ) return f();   
  4. // 假如我们已增加一个函数
  5. if ( domReady.timer ) {
  6. // 把它加入待执行的函数清单中
  7. domReady.ready.push( f );
  8. } else {
  9. // 为页面加载完成绑定一个事件,
  10. // 为防止它最先完成. 使用 addEvent(下面列出).
  11. addEvent( window, “load”, isDOMReady );   
  12. // 初始化待执行的函数的数组
  13. domReady.ready = [ f ];   
  14. // 经可能快地检查Dom是否已可用
  15. domReady.timer = setInterval( isDOMReady, 13 );
  16. }
  17. }  
  18. // 检查Dom是否已可操作
  19. function isDOMReady() {
  20. // 假如已检查出Dom已可用, 忽略
  21. if ( domReady.done ) return false;   
  22. // 检查若干函数和元素是否可用
  23. if ( document &&  document.getElementsByTagName &&  document.getElementById &&  document.body ) {   
  24. // 假如可用, 停止检查
  25. clearInterval( domReady.timer );
  26. domReady.timer = null;   
  27. // 执行所有等待的函数
  28. for ( var i = 0; i < domReady.ready.length; i++ )
  29. domReady.ready[i]();   
  30. // 记录在此已经完成
  31. domReady.ready = null;
  32. domReady.done = true;
  33. }
  34. }

  35. // 由 Dean Edwards 在2005 所编写addEvent/removeEvent,
  36. // 由 Tino Zijdel整理
  37. // http://dean.edwards.name/weblog/2005/10/add-event/
  38. //优点是1.可以在所有浏览器工作;
  39. //2.this指向当前元素;
  40. //3.综合了所有浏览器防止默认行为和阻止事件冒泡的的函数
  41. //缺点就是仅在冒泡阶段工作
  42. function addEvent(element, type, handler) {
  43.         // assign each event handler a unique ID
  44.         if (!handler.$$guid) handler.$$guid = addEvent.guid++;
  45.         // create a hash table of event types for the element
  46.         if (!element.events) element.events = {};
  47.         // create a hash table of event handlers for each element/event pair
  48.         var handlers = element.events[type];
  49.         if (!handlers) {
  50.                 handlers = element.events[type] = {};
  51.                 // store the existing event handler (if there is one)
  52.                 if (element["on" + type]) {
  53.                         handlers[0] = element["on" + type];
  54.                 }
  55.         }
  56.         // store the event handler in the hash table
  57.         handlers[handler.$$guid] = handler;
  58.         // assign a global event handler to do all the work
  59.         element["on" + type] = handleEvent;
  60. };
  61. // a counter used to create unique IDs
  62. addEvent.guid = 1;

  63. function removeEvent(element, type, handler) {
  64.         // delete the event handler from the hash table
  65.         if (element.events && element.events[type]) {
  66.                 delete element.events[type][handler.$$guid];
  67.         }
  68. };

  69. function handleEvent(event) {
  70.         var returnValue = true;
  71.         // grab the event object (IE uses a global event object)
  72.         event = event || fixEvent(window.event);
  73.         // get a reference to the hash table of event handlers
  74.         var handlers = this.events[event.type];
  75.         // execute each event handler
  76.         for (var i in handlers) {
  77.                 this.$$handleEvent = handlers[i];
  78.                 if (this.$$handleEvent(event) === false) {
  79.                         returnValue = false;
  80.                 }
  81.         }
  82.         return returnValue;
  83. };

  84. function fixEvent(event) {
  85.         // add W3C standard event methods
  86.         event.preventDefault = fixEvent.preventDefault;
  87.         event.stopPropagation = fixEvent.stopPropagation;
  88.         return event;
  89. };
  90. fixEvent.preventDefault = function() {
  91.         this.returnValue = false;
  92. };
  93. fixEvent.stopPropagation = function() {
  94.         this.cancelBubble = true;
  95. };
复制代码

[ 本帖最后由 zidanezhicong 于 2008-5-8 08:46 编辑 ]
已有 1 人评分威望 收起 理由
faeng220 + 1 谢谢分享

总评分: 威望 + 1   查看全部评分

西部数码顶级域名注册商39元抢注!
zidanezhicong 楼主

我爱阿仙奴

银牌会员 手机认证 

帖子
571
体力
2056
威望
1
居住地
广东省 深圳市
发表于 2008-5-8 08:52:23 |显示全部楼层
还有一个估计由几个外国大师合作写的,实现同样功能。
  1. /*
  2. * (c)2006 Jesse Skinner/Dean Edwards/Matthias Miller/John Resig
  3. * Special thanks to Dan Webb's domready.js Prototype extension
  4. * and Simon Willison's addLoadEvent
  5. *
  6. * For more info, see:
  7. * http://www.thefutureoftheweb.com/blog/adddomloadevent
  8. * http://dean.edwards.name/weblog/2006/06/again/
  9. * http://www.vivabit.com/bollocks/2006/06/21/a-dom-ready-extension-for-prototype
  10. * http://simon.incutio.com/archive/2004/05/26/addLoadEvent
  11. *
  12. *
  13. * To use: call addDOMLoadEvent one or more times with functions, ie:
  14. *
  15. *    function something() {
  16. *       // do something
  17. *    }
  18. *    addDOMLoadEvent(something);
  19. *
  20. *    addDOMLoadEvent(function() {
  21. *        // do other stuff
  22. *    });
  23. *
  24. */

  25. addDOMLoadEvent = (function(){
  26.     // create event function stack
  27.     var load_events = [],
  28.         load_timer,
  29.         script,
  30.         done,
  31.         exec,
  32.         old_onload,
  33.         init = function () {
  34.             done = true;

  35.             // kill the timer
  36.             clearInterval(load_timer);

  37.             // execute each function in the stack in the order they were added
  38.             while (exec = load_events.shift())
  39.                 exec();

  40.             if (script) script.onreadystatechange = '';
  41.         };

  42.     return function (func) {
  43.         // if the init function was already ran, just run this function now and stop
  44.         if (done) return func();

  45.         if (!load_events[0]) {
  46.             // for Mozilla/Opera9
  47.             if (document.addEventListener)
  48.                 document.addEventListener("DOMContentLoaded", init, false);

  49.             // for Internet Explorer
  50.             /*@cc_on @*/
  51.             /*@if (@_win32)
  52.                 document.write("<script id=__ie_onload defer src=//0><\/scr"+"ipt>");
  53.                 script = document.getElementById("__ie_onload");
  54.                 script.onreadystatechange = function() {
  55.                     if (this.readyState == "complete")
  56.                         init(); // call the onload handler
  57.                 };
  58.             /*@end @*/

  59.             // for Safari
  60.             if (/WebKit/i.test(navigator.userAgent)) { // sniff
  61.                 load_timer = setInterval(function() {
  62.                     if (/loaded|complete/.test(document.readyState))
  63.                         init(); // call the onload handler
  64.                 }, 10);
  65.             }

  66.             // for other browsers set the window.onload, but also execute the old window.onload
  67.             old_onload = window.onload;
  68.             window.onload = function() {
  69.                 init();
  70.                 if (old_onload) old_onload();
  71.             };
  72.         }

  73.         load_events.push(func);
  74.     }
  75. })();
复制代码

[ 本帖最后由 zidanezhicong 于 2008-5-8 08:54 编辑 ]
租服务器,上51IDC | [长沙]招聘:PHP经理10K/WEB前端6K/PHP开发6K

使用道具 举报

xilao 
帖子
49
体力
167
威望
0
居住地
广东省 广州市
发表于 2008-5-8 14:14:35 |显示全部楼层
还是不明白,能否说详细一些。用到哪个部位

使用道具 举报

汤海龙

银牌会员 手机认证 

帖子
2986
体力
2060
威望
0
居住地
广东省 珠海市
发表于 2008-5-8 15:26:24 |显示全部楼层
标记下!!
博客已挂

使用道具 举报

花会开

中级会员

帖子
157
体力
652
威望
0
居住地
山东省 菏泽市
发表于 2008-5-9 14:04:00 |显示全部楼层
研究下..

使用道具 举报

kyukoi 
帖子
49
体力
72
威望
0
发表于 2008-6-30 16:22:27 |显示全部楼层
标记下,有时间研究

使用道具 举报

resun 

寻寒

高级会员

帖子
219
体力
731
威望
0
发表于 2008-8-5 10:44:34 |显示全部楼层
做个标记,很有用的知识。
潔靜精微

使用道具 举报

帖子
119
体力
498
威望
0
发表于 2010-2-1 10:42:33 |显示全部楼层
这是一篇好文章。

使用道具 举报

帖子
436
体力
1127
威望
2
居住地
广西壮族自治区 钦州市
发表于 2010-2-1 11:25:39 |显示全部楼层
mark, 是该抽时间研究一下了..
for the alliance

使用道具 举报

莲心伊人

银牌会员

帖子
346
体力
1252
威望
0
居住地
广东省 深圳市
发表于 2010-2-1 12:12:16 |显示全部楼层
拜读一下

使用道具 举报

wtcsy 
帖子
54
体力
275
威望
0
居住地
广东省 深圳市
发表于 2010-2-1 12:16:08 |显示全部楼层

以前一直在找这个
今天终于找到了
mark下..............
我魔兽打的不错.

使用道具 举报

李惟

银牌会员 手机认证 

帖子
831
体力
2115
威望
0
发表于 2010-2-1 12:18:30 |显示全部楼层
推荐John Resig的《精通Javascript》,里面讲解的很详细

使用道具 举报

帖子
10
体力
59
威望
0
发表于 2010-2-1 15:07:50 |显示全部楼层
  支持顶一下。

使用道具 举报

您需要登录后才可以回帖 登录 | 注册

Archiver|手机版|安久科技提供CDN|blueidea.com ( 京ICP备05002321号 )  

GMT+8, 2012-2-13 11:19 , Processed in 0.104236 second(s), 11 queries , Gzip On, Memcache On.

Powered by Discuz! X2

© 2001-2011 Comsenz Inc.

回顶部