zoukankan      html  css  js  c++  java
  • DOM Ready

    一、说明 

    当页面有一个URL的时候,浏览器就会加载HTML,所有的HTML标签都转换完毕以后就叫做DOM树构建完毕。

    渲染引擎的职责就是把请求的内容显示在屏幕上,渲染引擎可以显示HTML,XML,图片。通过插件可以显示其他类型的文档。渲染引擎首先通过网络获得所请求的内容,通常以8k分块的方法来完成。

    这四步仅仅是HTML结构的渲染过程,并不包括加载外部的文件、脚本,外部文件的加载是贯穿HTML加载的整个过程.

    详细可参考  https://kb.cnblogs.com/page/129756/

    二、window.onload & domReady  

    window.onload是浏览完绘制完所有的节点,并且当页面上所有的资源加载完毕后再执行我们定义的业务逻辑,window.onload在外部资源(如:图片)不多的时候是没有什么问题的,但是当外部资源太多的时候,加载就会很慢,影响用户体验,这时可以把JQ的代码放在JS的ready回调里。即使用如下方法:

    $(document).ready(function(){
                 document.getElementById("header").style.color="orange";
             })
    

     

    在页面的DOM树创建完成后(也就是HTML解析完第一部完成)即触发,而无需等待其他资源加载。即DOMReady实现策略:

     1).支持DOMCotentLoaded事件的,就使用DOMContentLoaded事件

     2).不支持的,就用来自Diego Perini发现的著名Hack兼容,兼容原理大概就   是:通过IE中的document.docuemntElement.doScroll('left')来判断DOM树是否创建完毕。

    所以,是DOM文档加载的步骤为:

    1.解析HTML结构

    2.加载外部脚本和样式文件

    3.解析并执行脚本文件

    4.DOM树构建完成  会触发DOMcontentLoaded事件

    5.加载图片等外部文件

    6.页面加载完毕后会触发window.onload事件;

    DOMready会是在步骤4触发的  window.onload是在步骤6触发的  为了提高用户体验 你总不能等图片页面加载完才执行那些js代码吧 比如给页面上的按钮绑定点击事件 这样就很糟糕了

    PS: 插播一下

    递归函数(概念)

    递归函数即自调用函数,在函数体内部间接或者直接的自己调用自己,即函数的嵌套调用是函数本身。

    例如,下面的程序为求n!:   

          long fact(int n)   

          {   

           if(n==1)   

           return 1;   

           return fact(n-1)*n; //出现函数自调用   

          } 

    浏览器的Hack(概念)

    Hack是针对不同的浏览器去写不同的CSS样式,从而让各浏览器能达到一致的渲染效果,那么针对不同的浏览器写不同的CSS CODE的过程,就叫CSS HACK,同时也叫写CSS Hack。

    http://www.wufangbo.com/css-hack/

    https://blog.csdn.net/freshlover/article/details/12132801

    DOM Ready JS 

    function myReady(fn){
        /*对于现代浏览器,对DOMContentLoaded事件的处理采用标准的事件绑定方式
         这是典型的通过能力检测来区分浏览器的方法
         */
        if(document.addEventListener){
            document.addEventListener("DOMContentLoaded",fn,false)//DOM要大写
        }else{
            IEContentLoaded(fn);//对于IE低版本浏览器,就使用IE的dom加载
        }
    
        //IE模拟DOMContentLoaded
        function IEContentLoaded(fn){
            var d=window.document; //获取window下的doc
            var done=false;//定义一个标志变量
    
            //只执行一次用户的回调函数init()
            var init=function(){
                if(!done){
                    done=true;
                    fn();
                }
            };
            //如果document的状态加载未就绪,如何立即监测到并立即调用回调函数呢;先定义一段密集调用的函数表达式
            (function () {
                try{
                    //dom树未创建之前,调用doScroll的时候会抛出错误
                    d.documentElement.doScroll('left');
                }catch(e){
                    //y延迟再试一次
                    setTimeout(arguments.callee,50);
                    return;//return实现递归
                }
                init();
            })();
    
            //监听document的加载状态
            d.onreadystatechange=function () {
                //如果用户是在domReady之后绑定的函数,就立马执行
                if (d.readyState == "complete") {
                    d.onreadystatechange = null;
                    init();
                }
            }
        }
    }
    

    一个验证DOM Ready的实例:

    <!DOCTYPE html>
    <html lang="en">
    <head>
        <meta charset="UTF-8">
        <title>DOMReady综合案例</title>
        <script src="domReady.js"></script>
    </head>
    <body>
    <div id="showMsg"></div>
    <div >
        <img src="../images/1.jpg"/>
        <img src="../images/2.jpg"/>
        <img src="../images/3.jpg"/>
        <img src="../images/4.jpg"/>
        <img src="../images/5.jpg"/>
        <img src="../images/6.jpg"/>
    </div>
    
    <script type="text/javascript">
        var d=document;
        var msgBox=d.getElementById("showMsg");
        var img=d.getElementsByTagName("img");
        var time1=null, time2=null;
        myReady(function () {
            msgBox.innerHTML+="dom已加载!<br/>";
            time1=new Date().getTime();
            msgBox.innerHTML+="时间戳:"+time1+"<br/>";
        });
        window.onload=function(){
            msgBox.innerHTML+="onload已加载!<br/>";
            time2=new Date().getTime();
            msgBox.innerHTML+="domReady比onload快:"+(time2-time1)+"ms<br/>"
        };
    
       var isElement= function(el){
           return !!el&&el.nodeType===1;
       };
       console.log(document.getElementById("showMsg"));
    </script>
    </body>
    </html>
    

      

    var isElement= function(el){
    return !!el&&el.nodeType===1;
    };

    tips:

    !!一般用来将后面的表达式转换为布尔型的数据(boolean).  因为javascript是弱类型的语言(变量没有固定的数据类型)所以有时需要强制转换为相应的类型,类似的如:
    a=parseInt("1234"); a="1234"+0 //转换为数字 b=1234+"" //转换为字符串 c=someObject.toString() //将对象转换为字符串 其中第1种、第4种为显式转换,2、3为隐式转换.
    布尔型的转换,javascript约定和c类似,规则为 : false、undefinded、null、0、"" 为 false ; true、1、"somestring"、[Object] 为 true .
    !!el表示判断是否el存在,存在为true,反之为false.

     

  • 相关阅读:
    CSS进阶-深入理解vertical-align和line-height的关系
    困难的串【转】
    【转】常用 Git 命令清单
    程序员常用等宽字体
    IE的特有属性hasLayout和BFC
    css深入理解之行高line-height
    mysql 索引优化,不走索引的原因
    php解决高并发(文件锁)
    mysql索引详解
    http错误代码
  • 原文地址:https://www.cnblogs.com/potato-lee/p/8849761.html
Copyright © 2011-2022 走看看