DOM Ready探究

2024-05-02 17:32
文章标签 dom 探究 ready

本文主要是介绍DOM Ready探究,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

        文档对象模型(Document Object Model,简称DOM),是W3C组织推荐的处理可扩展标志语言的标准编程接口。在网页上,组织页面(或文档)的对象被组织在一个树形结构中,用来表示文档中对象的标准模型就称为DOM。

        我们常说的DOM分为DOM 1,DOM 2,DOM 3。DOM0实际上是不存在的,而它实际上是在IE 4时代出现的DHTML。再具体来说,DOM 1包括DOM Core(核心)、DOM HTML(针对HTML)。DOM 2包括DOM Views(视图)、DOM Event(事件)、DOM Style(基于CSS的样式)、DOM Traversal and Range(遍历和范围)。DOM 3包括 DOM Load and Save(模块加载和存储)、DOM Validation(验证)。

        首先,我们举一个例子:


        在这段代码中,我们通过获取id为content的h1标签来给它添加了文字的颜色,我们来看看效果:


        效果并没有实现,而且还有报错:


        这是为什么呢?首先我们进入了理解的盲区,我们错把HTML中的元素理解成为了DOM节点,而两者是有本质区别的。

        在此我们先来说说浏览器渲染引擎的基本流程:

                一,解析HTML,构建DOM树;————构建DOM节点

                二,构建渲染树;——————————解析样式信息

                三,布局渲染树;——————————布局DOM节点

                四,绘制渲染树;——————————绘制DOM节点

        指得一提的是在渲染的过程中外部资源始终都在加载。

        这里找到一张webkit引擎的主要渲染流程图:

                

        其实说这些就是为了便于理解为什么在上边的demo中会报错。DOM树的建立是在HTML文档加载之前,所以根本获取不到节点。


        那么重点终于来了。我们如何解决这个问题?

        一,把JS代码写在HTML文档最后。

              好吧,第一种方法永远是最傻的。道理很简单,在较大的项目中需要多个JS代码植入,都写在下面岂不乱哉。

        二,setTimeout()

              这个很好理解,就是强行加入一个人为设定的时间。显然,这样做不合理且效率低。

        三,使用window.onload

              window.onload指的就是在HTML文档加载完之后再触发事件,这样就会相对舒服的避免了找不到对象的问题。但是,我们多思考一些,文档加载完?在前文中提到了外部资源始终都在加载,如果网速不给力、外部资源过多那很有可能我们在window.onload中写的所有所有所有代码都不会生效。这个问题很严重,于是第三种方法应运而生。

        四,DOM Ready

             英雄总是最后一个登场~  首先上代码

<script>function myReady(fn){		//fn就是以后的回调函数// 对于现代浏览器,对DOMContentLoaded事件的处理方式采用的是标准的事件绑定方式if(document.addEventListener){document.addEventListener("DOMContentLoaded", fn, false);		//通过绑定事件来侦测DOMReady,冒泡阶段捕获}else{IEContentLoaded(fn);}// IE模拟DOMCOntentLoadedfunction IEContentLoaded(fn){var d = window.document;var done = false;// 定义保证只执行一次用户回调的init()函数var init = function(){if(!done){done = true;fn();}};//侦测DOMReady并立即调用回掉函数方法(function(){try{// DOM 树未创建前调用doScroll会抛出错误d.documentElement.doScroll("left");		//如果DOM树没创建完就会抛出错误}catch(e){//延迟再试一次setTimeout(arguments.callee, 50);return;}// 没有错误就表示DOM树创建完毕,然后立马执行回掉函数init();})();// 监听document的加载状态d.onreadystatechange = function(){// 如果用户实在domReady之后绑定的函数,就立即执行if(d.readyState == "complete"){d.onreadystatechange = null;	//清除掉init();}}}}

        注释写的很清楚,主要再来说一下思路:使用DOM Ready的关键是DOMContentLoaded事件。这个事件是用来判断DOM树是否加载完,就是解析HTML的第一步,如果加载完成就立刻绑定事件到元素。

       做好完美从来都不容易。定义了IEContentLoad()函数就是为了解决IE无法识别该事件的问题。思路是这样的:首先,能够实现效果的核心是利用IE中的documntElement.doScroll("left")方法来判断DOM树是否创建完毕。

第一步,定义init()回调函数,保证在DOM Ready后只执行一次。

第二步,定义了onreadystatechange()函数来监听document的加载状态(注:代码中将document存在了变量d中)。通过if语句判断document是否加载完成。这里利用readState方法,判断其值是否为complete。这时候将onreadystatechange事件清除掉,因为每当 readyState 改变时,就会触发 onreadystatechange 事件,这里涉及到Ajax的相关知识。之后再执行init()完成document的加载判定。

最后一步,定义一个自调函数来解决如果document加载的状态未就绪如何侦测到DOM Ready并立即调用回调函数。这里就利用到了documntElement.doScroll("left")方法在DOM树没加载完时会抛出错误的特点(注:left是随便传的),配合try...catch语句再实现延迟调用。延迟调用这里利用到了arguments.callee属性来使这个匿名函数实现调用。最后用return;实现递归。直到没有错误时就确保了了DOM树创立完毕并立刻执行回调。

        OK~解释了这么多我们来看看效果。依然是最初的那个demo,我们来试一试:

        使用我们的函数:


        效果:

         

        Bingo~达到了我们的效果~

       

        我们写一个测试实施效果~:

HTML代码:

<body><div id="show"></div><div><img src="1.jpg" alt=""><img src="2.jpg" alt=""><img src="3.jpg" alt=""><img src="4.jpg" alt=""><img src="5.jpg" alt=""><img src="6.jpg" alt=""></div>
</body>


JS代码:

var time1 = null;
var time2 = null;myReady(function(){var msgBox = document.getElementById("show");var imgs = document.getElementsByTagName("img");msgBox.innerHTML += "DOM加载完成</br>";time1 = new Date().getTime();msgBox.innerHTML += "时间:" + time1 + "</br>";});window.onload = function(){var msgBox = document.getElementById("show");var imgs = document.getElementsByTagName("img");msgBox.innerHTML += "window.onload加载完成</br>";time2 = new Date().getTime();msgBox.innerHTML += "时间:" + time2 + "</br>";msgBox.innerHTML += "DOM Ready比window.onload快" + (time2 - time1) + "毫秒</br>";}

        显而易见的结果~

            


        最后,附上找到的jquery的DOM Ready方法:

function jQuery(a,c) {if ( a && a.constructor == Function && jQuery.fn.ready ){return jQuery(document).ready(a);}}jQuery.fn.extend({ready: function(f) {if ( jQuery.isReady )f.apply( document );else {jQuery.readyList.push( f );}        return this;}});jQuery.extend({isReady: false,readyList: [],ready: function() {if ( !jQuery.isReady ) {jQuery.isReady = true;if ( jQuery.readyList ) {for ( var i = 0; i < jQuery.readyList.length; i++ )jQuery.readyList[i].apply( document );jQuery.readyList = null;}}}});new function(){if ( jQuery.browser.mozilla || jQuery.browser.opera ) {document.addEventListener( "DOMContentLoaded", jQuery.ready, false );} else if ( jQuery.browser.msie ) {document.write("<scr" + "ipt id=__ie_init defer=true " + "src=//:><\/script>");var script = document.getElementById("__ie_init");script.onreadystatechange = function() {if ( this.readyState == "complete" )jQuery.ready();};script = null;} else if ( jQuery.browser.safari ) {jQuery.safariTimer = setInterval(function(){if ( document.readyState == "loaded" || document.readyState == "complete" ) {clearInterval( jQuery.safariTimer );jQuery.safariTimer = null;jQuery.ready();}}, 10);} jQuery.event.add( window, "load", jQuery.ready );    }


这篇关于DOM Ready探究的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/954782

相关文章

Android平台播放RTSP流的几种方案探究(VLC VS ExoPlayer VS SmartPlayer)

技术背景 好多开发者需要遴选Android平台RTSP直播播放器的时候,不知道如何选的好,本文针对常用的方案,做个大概的说明: 1. 使用VLC for Android VLC Media Player(VLC多媒体播放器),最初命名为VideoLAN客户端,是VideoLAN品牌产品,是VideoLAN计划的多媒体播放器。它支持众多音频与视频解码器及文件格式,并支持DVD影音光盘,VCD影

Codeforces Round #240 (Div. 2) E分治算法探究1

Codeforces Round #240 (Div. 2) E  http://codeforces.com/contest/415/problem/E 2^n个数,每次操作将其分成2^q份,对于每一份内部的数进行翻转(逆序),每次操作完后输出操作后新序列的逆序对数。 图一:  划分子问题。 图二: 分而治之,=>  合并 。 图三: 回溯:

17 通过ref代替DOM用来获取元素和组件的引用

重点 ref :官网给出的解释是: ref: 用于注册对元素或子组件的引用。引用将在父组件的$refs 对象下注册。如果在普通DOM元素上使用,则引用将是该元素;如果在子组件上使用,则引用将是组件实例: <!-- vm.$refs.p will be the DOM node --><p ref="p">hello</p><!-- vm.$refs.child will be the c

react笔记 8-19 事件对象、获取dom元素、双向绑定

1、事件对象event 通过事件的event对象获取它的dom元素 run=(event)=>{event.target.style="background:yellowgreen" //event的父级为他本身event.target.getAttribute("aid") //这样便获取到了它的自定义属性aid}render() {return (<div><h2>{

DOM 添加节点

DOM 添加节点 在Web开发中,文档对象模型(DOM)是一个非常重要的概念。DOM是HTML和XML文档的编程接口,它将文档表示为节点树,允许开发人员通过JavaScript等脚本语言进行操作。在本文中,我们将探讨如何在DOM中添加节点,包括各种方法和最佳实践。 DOM节点简介 在DOM中,文档的每一个部分都是一个节点。主要的节点类型包括: 元素节点:HTML标签,例如<div>或<sp

js操作Dom节点拼接表单及ajax提交表单

有时候我们不希望html(jsp、vm)中有创建太多的标签(dom节点),所以这些任务都由js来做,下面提供套完整的表单提交流程,只需要在html中添加两个div其余的都由js来做吧。下面原生代码只需略微修改就能达到你想要的效果。 1、需要创建表单的点击事件 <a href="javascript:void(0);"onclick="changeSettleMoney('$!doctor.do

WebAPI (一)DOM树、DOM对象,操作元素样式(style className,classList)。表单元素属性。自定义属性。间歇函数定时器

文章目录 Web API基本认知一、 变量声明二、 DOM1. DOM 树2. DOM对象3. 获取DOM对象(1)、选择匹配的第一个元素(2)、选择匹配多个元素 三、 操作元素1. 操作元素内容2. 操作元素属性(1)、常用属性(href之类的)(2)、通过style属性操作CSS(3)、通过类名(className)操作CSS(4)、通过classList操作控制CSS(5)、操作表单

javaweb-day01-6(XML 解析 - Jaxp的DOM方式解析)

Jaxp解析开发包     JAXP 开发包是J2SE的一部分,它由javax.xml、org.w3c.dom 、org.xml.sax 包及其子包组成  在 javax.xml.parsers 包中,定义了几个工厂类,程序员调用这些工厂类,可以得到对xml文档进行解析的DOM 或SAX 的解析器对象。   DOM解析方式: 步骤: 1.        调用javax.xml.

jquery对象和dom对象-比较

jquery对象和dom对象-比较 1、关于页面元素的引用 通过jquery的$()引用元素包括通过id、class、元素名以及元素的层级关系及dom或者xpath条件等方法,且返回的对象为jquery对象(集合对象),不能直接调用dom定义的方法。 DOM对象转jQuery对象 普通的Dom对象一般可以通过$()转换成jQuery对象。 如:$(document.getElementByI

探究零工市场小程序如何改变传统兼职模式

近年来,零工市场小程序正逐渐改变传统的兼职模式,为求职者和雇主提供了一个更为高效、便捷的平台。本文将深入探讨零工市场小程序如何影响传统兼职模式,以及它带来的优势和挑战。 一、背景与挑战 传统的兼职市场往往存在信息不对称的问题,求职者难以快速找到合适的工作,而雇主也难以找到匹配的劳动力。此外,兼职工作的不稳定性和安全性也是求职者关注的焦点。零工市场小程序的兴起,旨在解决这些问题,通过数字化手