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方法:


<!DOCTYPE html>
  <html>  
  <head> 
    <meta http-equiv="Content-Type" content="text/html; charset=utf-8">
    <!--The viewport meta tag is used to improve the presentation and behavior of the samples 
      on iOS devices-->
    <meta name="viewport" content="initial-scale=1, maximum-scale=1,user-scalable=no"/>
    <title>MyDomReady</title>
    
    <script type="text/javascript">
        window.myDOMReady = function(callback){
            myDOMReady.isReady = false;
            
            var isBindReady = false;
            if (typeof callback === "function"){
                myDOMReady.readyCallback = callback;
            }else{
                myDOMReady.readyCallback = function(){};
            }
            
            bindReady();
            
            function onReady(){
                console.log("onReady Function");
                if (!myDOMReady.isReady){
                    if (!document.body){
                        setTimeout(onReady, 4);
                        return;
                    }
                    myDOMReady.isReady = true;
                    console.log('ready');
                    myDOMReady.readyCallback();
                }
            };
            
            function domReady(){
                if (document.addEventListener){
                    console.log('DOMContentLoaded');
                }else if (document.attachEvent){
                    console.log("onreadystatechange   ", document.readyState);
                }
                onReady();
            }
            
            function bindReady(){
                if (isBindReady){
                    return;
                }
                isBindReady = true;
                
                if (document.addEventListener){
                    document.addEventListener('DOMContentLoaded', domReady, false);
                }else if (document.attachEvent){
                    document.attachEvent('onreadystatechange', domReady);
                    
                    var hasDoScroll = !!document.documentElement.doScroll,
                    noFrame = window.frameElement === null;
                    if (hasDoScroll && noFrame){
                        checkDoScroll();
                    }
                }
                window.onload = function(){
                    console.log('onloaded');
                    onReady();
                };
            };
            
            function checkDoScroll(){
                if (myDOMReady.isReady){
                    return;
                }
                try{
                    document.documentElement.doScroll('left');
                }catch(err){
                    setTimeout(checkDoScroll, 4);
                    return;
                }
                console.log('checked');
                onReady();
            };
        };
    </script>
    <script type="text/javascript">
        myDOMReady(function(){
            var map = document.getElementById('map');
            if (map){
                alert('Yes');
            }else{
                alert('No!');
            }
        });
        var map2 = document.getElementById('map');
            if (map2){
                alert('Yes');
            }else{
                alert('No!');
            }
    </script>
  </head> 

  <body class="claro"> 
  <input id="ipt" type="file" accept="image/png" >
    <div data-dojo-type="dijit/layout/BorderContainer" 
         data-dojo-props="design:'headline', gutters:false" 
         style="width:100%;height:100%;margin:0;">
        
      <div id="map" 
           data-dojo-type="dijit/layout/ContentPane" 
           data-dojo-props="region:'center'" 
           style="padding:0;">

        <div style="position:absolute; right:20px; top:10px; z-Index:999;">
          <div data-dojo-type="dijit/TitlePane" 
               data-dojo-props="title:'Switch Basemap', closable:false,  open:false">
            <div data-dojo-type="dijit/layout/ContentPane" style="width:380px; height:280px; overflow:auto;">
            <div id="basemapGallery" ></div></div>
          </div>
        </div>

      </div>
    </div>
  </body> 

  </html>

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

 

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


目录
相关文章
|
JavaScript
Dom onload和jQuery document ready的区别
Dom onload和jQuery document ready的区别
Dom onload和jQuery document ready的区别
|
1月前
|
JavaScript 前端开发
JavaScript操作DOM元素
JavaScript操作DOM元素
12 1
|
1月前
|
JavaScript 前端开发
如何使用 JavaScript 操作 DOM?
如何使用 JavaScript 操作 DOM?
13 0
|
4月前
|
JavaScript 前端开发
JavaScript DOM 操作:什么是事件委托(Event Delegation)?有什么优势?
JavaScript DOM 操作:什么是事件委托(Event Delegation)?有什么优势?
56 1
|
4月前
|
JavaScript 前端开发
JavaScript DOM 操作:如何动态创建和插入元素?
JavaScript DOM 操作:如何动态创建和插入元素?
44 1
|
4月前
|
JavaScript 前端开发 安全
JavaScript DOM 操作:解释一下 `innerHTML` 和 `textContent` 的区别。
JavaScript DOM 操作:解释一下 `innerHTML` 和 `textContent` 的区别。
42 1
|
3天前
|
JavaScript 前端开发 UED
深入解析JavaScript原生操作DOM技术
【4月更文挑战第22天】本文深入探讨JavaScript原生DOM操作技术,包括使用`getElement*`方法和CSS选择器获取元素,借助`createElement`与`appendChild`动态创建及插入元素,修改元素内容、属性和样式,以及删除元素。通过掌握这些技术,开发者能实现页面动态交互,但应注意避免过度操作DOM以优化性能和用户体验。
|
10天前
|
存储 JavaScript 前端开发
JavaScript DOM 操作:解释一下 cookie、sessionStorage 和 localStorage 的区别。
Cookie是服务器发送至客户端的文本信息,会随每个请求发送回服务器,适合控制会话状态但可能暴露隐私。SessionStorage仅在当前会话中存储数据,关闭浏览器后清除,适合临时存储如登录状态。LocalStorage则持久保存数据,即使关闭浏览器也不会清除,适用于存储长期设置。三种方式各有侧重,应按需求选择。
15 0
|
10天前
|
JavaScript 前端开发 安全
JavaScript DOM 操作:解释一下浏览器的同源策略。
**同源策略**是浏览器安全基石,它阻止脚本跨不同协议、域名或端口访问资源,防止恶意行为。例如,HTTP页面无法直接用JS获取HTTPS页面内容。**CORS**允许跨域请求,但需服务器配合设置,通过`document.domain`属性可配置,但仍受限于服务器配置。
14 4
|
23天前
|
JavaScript 前端开发
深入了解 JavaScript 中的 DOM 和 BOM
深入了解 JavaScript 中的 DOM 和 BOM
18 4