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中的测试结果

 

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

时间: 2024-08-31 09:00:57

DOM何时Ready的相关文章

jquery中ready()函数执行的时机和window的load事件比较

  这篇文章主要介绍了jquery中ready()函数执行的时机和window的load事件比较的相关资料,需要的朋友可以参考下 jquery的ready()实现的是 DOMContentLoaded 事件,DOMContentLoaded与window load事件的区别 简单的说ready()是在文档加载完成就会触发,此时图片等资源可能还没有完全加载, load是在所有资源都加载完成后才会触发 看下ready函数的代码就什么都清楚了.下面的代码加上了注释: ? 1 2 3 4 5 6 7 8

《jQuery Cookbook中文版》——1.2 在DOM加载之后、整个页面加载之前执行jQuery/JavaScript代码

1.2 在DOM加载之后.整个页面加载之前执行jQuery/JavaScript代码 1.2.1 问题 采用无干扰式JavaScript方法论的现代JavaScript应用程序通常只在DOM完全加载之后才执行JavaScript.实际情况是,任何DOM遍历和操纵都要求在操作之前必须加载DOM.需要一种手段来确定客户端(最常见的是Web浏览器)何时完成DOM的加载(这时图片和SWF文件等资源可能还没有完全加载).如果在这种情况下使用window.onload事件,包括所有资源的整个文档完全加载之后

模拟jQuery中的ready方法及实现按需加载css,js实例代码_jquery

一.ready函数的实现经常用jQuery类库或其他类库中的ready方法,有时候想想它们到底是怎么实现的,但是看了一下jQuery中的源码,涉及到的模块比较多,(水平有限)代码比较难看懂:自己结合了一些书籍内容,总结一下.先说一下ready函数的实现思路:变量ready通过表达式赋值,右侧为一个自执行匿名函数,在这个匿名函数中,首先为各个浏览器的事件绑定处理函数,并为isReady赋值(根据事件异步处理程序来确定),然后返回一个传参闭包,在闭包中,主要判断isReady值来执行操作,如果dom

jquery ready函数深入分析_C 语言

最近看一些关于jquery ready 有人说他缓慢,有人说他快,说法不一. 于是自己深入研究一下.首先看了一下jquery 文档 关于ready 的描述 While JavaScript provides the load event for executing code when a page is rendered, this event does not get triggered until all assets such as images have been completely

jQuery中的ready函数与window.onload谁先执行_jquery

A.关于$(document).ready(): jquery中的$(document).ready(),那$(document).ready()到底是什么作用呢?是不是可以用window.onload = function(){ ... }来实现呢? 这里,我们要明确二者之间的区别. 我们使用window.onload = function(){ ... },是希望在页面被载入时执行function中的处理,但是这些JS代码只有在页面上的全部内容加载完成(包括头部的banner广告,所有图片)

jQuery实现DOM加载方法源码分析

传统的判断dom加载的方法 使用 dom0级 onload事件来进行触发所有浏览器都支持在最初是很流行的写法 我们都熟悉这种写法: window.onload=function(){             ...           }  但是onload事件触发过于缓慢,尤其是在存在很多外部图片或者视频文件的时候,为了更好的了解这一点有必要知道一个html文档是如何进行加载的,这里引用一个园友的表述: 1.用户输入网址(假设是个html页面,并且是第一次访问),浏览器向服务器发出请求,服务器

Javascript模块化编程(三):require.js的用法

今天介绍如何将它们用于实战. 我采用的是一个非常流行的库require.js. 一.为什么要用require.js? 最早的时候,所有Javascript代码都写在一个文件里面,只要加载这一个文件就够了.后来,代码越来越多,一个文件不够了,必须分成多个文件,依次加载.下面的网页代码,相信很多人都见过. <script src="1.js"></script> <script src="2.js"></script> &

mootools【十】- window的扩展及多彩世界

一.Mootools框架对Window的扩展: 浏览器的window对象本身就提供了我们很多的对浏览器本身属性的获取或设置的方法,但是我们也知道,由于各大浏览器之间对标准的实现不统一,导致很多方法功能上有所出入,mootools为我们统一了我们最常用的一些方法: mootools的Window.Base.js里面,主要实现了对DOM树创建完成的事件监听.以前,我们可能经常把javascript代码写在html代码的最后面获者加上defer属性,以保证javascript代码要操作的html先于j

js文本框中禁止非数字字符输入

 <!DOCTYPE HTML> <html lang="en-US"> <head> <meta charset="UTF-8"> <title></title> <link rel="stylesheet" href="style.css"> </head> <script src="http://libs.ba