zoukankan      html  css  js  c++  java
  • DOM何时Ready

      由于script标签在被加载完成后会立即执行其中代码,如果在代码中要访问HTMLElement,可是这时候元素还没有加载进来,所以对元素的操作统统无效。

      最早的时候使用window.onload = function(){...},使得代码在页面完全加载完成后执行,这种方法对于页面资源很小的情况下是没问题的。弊端在于有时候页面中回加载一些比较费时的img、flash等资源,这种情况下浏览器会一直等待这些资源加载完成后再执行js代码。而浏览器中有DOM树跟Render树的区分,我们当然希望DOM树生成后便可以执行js代码,而不需要一定等待Render树完成后采取执行。

      HTML5中加入了DOMContentLoaded事件,该事件在DOM树加载完成后便会触发(实际上大多数浏览器通常在样式资源加载完成后才会触发该事件,这个时候DOM可能早就加载完成了)。

      对于不支持DOMContentLoaded事件的浏览器,我们通过监听document的onreadystatechange事件来判断DOM加载情况。从理论上来说,document有一属性名唤readyState,在页面加载过程中该属性的值会经过三次变化:loading(加载阶段)、interactive(DOM解析完成)、complete(完全加载完成,相当于onload)。但是浏览器的有时候并不会依次经过这三次变化。

      在IE中有某些DOM方法,必须在DOM加载完成后方可调用(注意是调用,不是访问),一般情况下通过轮询调用doScroll方法来检测,当调用成功时表明DOM已加载完成。但需要注意的是,当页面中有iframe元素时,会等到iframe完全渲染结束后,调用才可成功,这时候于调用onload方法没什么区别。还有一点,在IE中,document.body必须在DOM解析完成后才可以访问body元素,而FF中即使DOM没有加载完成也可访问,这一点经常在IE中被用作判断DOM加载完成时的一个依据。

      下面是参考资料后,自己写的一个domready方法:

      1 <!DOCTYPE html>
      2   <html>  
      3   <head> 
      4     <meta http-equiv="Content-Type" content="text/html; charset=utf-8">
      5     <!--The viewport meta tag is used to improve the presentation and behavior of the samples 
      6       on iOS devices-->
      7     <meta name="viewport" content="initial-scale=1, maximum-scale=1,user-scalable=no"/>
      8     <title>MyDomReady</title>
      9     
     10     <script type="text/javascript">
     11         window.myDOMReady = function(callback){
     12             myDOMReady.isReady = false;
     13             
     14             var isBindReady = false;
     15             if (typeof callback === "function"){
     16                 myDOMReady.readyCallback = callback;
     17             }else{
     18                 myDOMReady.readyCallback = function(){};
     19             }
     20             
     21             bindReady();
     22             
     23             function onReady(){
     24                 console.log("onReady Function");
     25                 if (!myDOMReady.isReady){
     26                     if (!document.body){
     27                         setTimeout(onReady, 4);
     28                         return;
     29                     }
     30                     myDOMReady.isReady = true;
     31                     console.log('ready');
     32                     myDOMReady.readyCallback();
     33                 }
     34             };
     35             
     36             function domReady(){
     37                 if (document.addEventListener){
     38                     console.log('DOMContentLoaded');
     39                 }else if (document.attachEvent){
     40                     console.log("onreadystatechange   ", document.readyState);
     41                 }
     42                 onReady();
     43             }
     44             
     45             function bindReady(){
     46                 if (isBindReady){
     47                     return;
     48                 }
     49                 isBindReady = true;
     50                 
     51                 if (document.addEventListener){
     52                     document.addEventListener('DOMContentLoaded', domReady, false);
     53                 }else if (document.attachEvent){
     54                     document.attachEvent('onreadystatechange', domReady);
     55                     
     56                     var hasDoScroll = !!document.documentElement.doScroll,
     57                     noFrame = window.frameElement === null;
     58                     if (hasDoScroll && noFrame){
     59                         checkDoScroll();
     60                     }
     61                 }
     62                 window.onload = function(){
     63                     console.log('onloaded');
     64                     onReady();
     65                 };
     66             };
     67             
     68             function checkDoScroll(){
     69                 if (myDOMReady.isReady){
     70                     return;
     71                 }
     72                 try{
     73                     document.documentElement.doScroll('left');
     74                 }catch(err){
     75                     setTimeout(checkDoScroll, 4);
     76                     return;
     77                 }
     78                 console.log('checked');
     79                 onReady();
     80             };
     81         };
     82     </script>
     83     <script type="text/javascript">
     84         myDOMReady(function(){
     85             var map = document.getElementById('map');
     86             if (map){
     87                 alert('Yes');
     88             }else{
     89                 alert('No!');
     90             }
     91         });
     92         var map2 = document.getElementById('map');
     93             if (map2){
     94                 alert('Yes');
     95             }else{
     96                 alert('No!');
     97             }
     98     </script>
     99   </head> 
    100 
    101   <body class="claro"> 
    102   <input id="ipt" type="file" accept="image/png" >
    103     <div data-dojo-type="dijit/layout/BorderContainer" 
    104          data-dojo-props="design:'headline', gutters:false" 
    105          style="100%;height:100%;margin:0;">
    106         
    107       <div id="map" 
    108            data-dojo-type="dijit/layout/ContentPane" 
    109            data-dojo-props="region:'center'" 
    110            style="padding:0;">
    111 
    112         <div style="position:absolute; right:20px; top:10px; z-Index:999;">
    113           <div data-dojo-type="dijit/TitlePane" 
    114                data-dojo-props="title:'Switch Basemap', closable:false,  open:false">
    115             <div data-dojo-type="dijit/layout/ContentPane" style="380px; height:280px; overflow:auto;">
    116             <div id="basemapGallery" ></div></div>
    117           </div>
    118         </div>
    119 
    120       </div>
    121     </div>
    122   </body> 
    123 
    124   </html>

      以下为chrome、FF、IE9和IE7、8中的测试结果

      本人能力有限,其中有不足的地方欢迎各位道友不吝指正

  • 相关阅读:
    51NOD 1069 Nim游戏
    51NOD 1066 Bash游戏
    51NOD 1058 N的阶乘的长度
    51NOD 1057 N的阶乘
    51NOD 1027 大数乘法
    RMQ 区间最大值 最小值查询
    Codeforces Round #426 (Div. 2) C. The Meaningless Game
    51NOD 1046 A^B Mod C
    OJ上 编译器 G++和C++的区别
    二分暑假专题 训练记录 2017-7-29
  • 原文地址:https://www.cnblogs.com/dojo-lzz/p/3660756.html
Copyright © 2011-2022 走看看