zoukankan      html  css  js  c++  java
  • window.onload与DOM树 (转载)

        先看一下问题:

    1 window.onload=function(){
    2       createDom();
    3       operateDom();
    4       //code stuff
    5 }
        其中 createDom()通过异步请求取得大量数据,然后组织起来;operateDom()是通过遍历操作createDom生成的节点。问题出现了:页面显示的并不是我们想要的效果。为什么?operateDom并不能总是取到生成的dom节点。由于生成的dom节点附加到页面dom树的时候存在着延迟,所以在createDom里面数据量比较大、生成dom节点比较多的时候,这种时间差会很大(对机器而言)。虽然createDom里面的语句执行完毕,接下来执行operateDom,但那些生成的节点也许还没有完全附加到dom树上面,所以就存在取不到dom节点的情况。
        也许你会想,为什么不直接在createDom里面在生成那些dom的时候直接操作,而是重新进行遍历操作?问题在于createDom和operateDom并不是同一个开发人员写的,也有可能是调用公用的东西,所以更不可能去改createDom了。这里只是为了举例方便。
        怎么办?setTimeout?setTimeInterval?
        setTimeout自然不可取,我们并不知道时间差是多少,设的太长了,用户体验不好,设的太短了,达不到我们的目的。setTimeInterval可以,但这会频繁的执行,我们只需要它执行一次。针对setTimeInteval,折中的解决办法是设置哨位监视。改动一下:
    1 operateDom(){
    2     if(operateDom.called)
    3        return;
    4     // code stuff
    5 }
        问题解决了?没有。我们要操作的是Dom,onload会直到页面所有内容都加载完成才执行。如果页面有太多的图片,那就只用等了。对用户来说,等的时间就是加载图片的时间,然后加上我们处理dom节点的时间,用户体验就差了。我们需要的仅仅是dom加载完成!
        对Mozilla系列的浏览器(如ff/googlechrome),可以:
    1 // for Mozilla browsers
    2 if (document.addEventListener) {
    3    document.addEventListener("DOMContentLoaded", init, false);
    4 }
        其中init执行createDom和修改后的operateDom.下同。
        IE支持条件编译(js是解释执行的,这里找不到合适的词来表述,看下面的代码就知道了)。在IE系列的浏览器中,可以:

    1  // for Internet Explorer
    2  /*@cc_on @*/
    3  /*@if (@_win32)
    4    document.write("<script defer src=ie_onload.js><"/script>");
    5  /*@end @
        如果在页面里面这么写:

    <!--[if IE]><script defer src="ie_onload.js"></script><![endif]
        在IE系列的浏览器是正常的,其它浏览器会忽略defer属性,将外部js文件加载进来。这里ie_onload.js里面只有init函数。 对其它系列的浏览器,这么写: window.onload=init. 综合起来,init就会执行多次了,就不是一次。同上面处理operateDom一样,给init增加一个哨位即可:     1 function init() {
     2   // quit if this function has already been called
     3   if (arguments.callee.done) return;
     4 
     5   // flag this function so we don't do the same thing twice
     6   arguments.callee.done = true;
     7 
     8   createDom();
     9   setTimeInterval("operateDom()",100);
    10   // do stuff
    11 };

       至此,问题解决。

    参考资料:The window.onload Problem - Solved!

    转自:http://www.cnblogs.com/huankfy/articles/1285759.html
  • 相关阅读:
    Codeforces Round #369 (Div. 2)
    Codeforces Round #361 (Div. 2)
    【转】.NET开发人员的瓶颈和职业发展
    【资料目录收藏】.NET开发必看资料53个 经典源码77个
    IT新人养成与蘑菇理论
    软件开发技术高手转向项目管理者要突破的误区
    关于程序猿的那些笑话
    工作流管理系统的应用
    工作流管理系统的标准和产品
    工作流系统的主要组成部分
  • 原文地址:https://www.cnblogs.com/johnwonder/p/1894920.html
Copyright © 2011-2022 走看看