DOM 文档对象模型、domReady、window.onload与$(document).ready()
一个完整的JavaScript由三个不同的部分组成:核心(ECMAScript)、文档对象模型(DOM)、浏览器对象模型(BOM)。
DOM
文档对象模型(DOM,Document, Object Model)是针对XML但经过扩展用于HTML的应用程序编程接口(API,Application Programming Interface)。DOM把整个页面映射为一个多层次节点结构。HTML或XML页面中的每次组成部分都是某种类型的节点,这些节点又包含着不同类型的数据。
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>认识DOM</title>
</head>
<body>
<p>文档对象模型</p>
</body>
</html>
上述的结构可以通过下图表示:
通过DOM创建的这个表示文档的树形图,开发人员获得了控制页面的内容和结构的主动权。借助DOM提供的API,开发人员可以
1.为什么要是使用DOM?
因为Internet Explorer 4和Netscape Navigator 4分别支持不同形式的DHTML(Dynamic HTML)基础上, 开发人员 无需首次无需重新加载网页,可以修改其外观和内容。但是两大公司的内容互不兼容,所以负责制定Web通信标准的W3C(World Wide Web Consortinm,万维网联盟)开始制定DOM。
2.DOM级别
DOM1(DOM Level 1) DOM1级由两个模块组成:DOM核心(DOM core)和DOM HTML。其中DOM核心规定,的是如何映射基于XML的文档结构,以便简化对文档中任意部分的访问和操作。DOM HTML 模块则在核心的基础上加以扩展,添加了针对HTML的对象和方法。目标主要是映射文档的结构。
DOM2在DOM1的基础上添加了鼠标用户点击事件、范围遍历等细分模块,而且支持了CSS(Cascading Style Sheets, 层叠样式表)。
DOM2引入了新模块,也给出了新类型和新接口:
DOM视图(DOM views):定义了跟踪不同文档视图的接口
DOM事件(DOM events):定义了事件和事件处理的接口
DOM样式(DOM style):定义了基于CSS为元素应用样式的接口
DOM遍历和范围(DOM Traversal and Range):定义了遍历和操作文档树的接口
DOM3 引入了统一方式加载和保存文档的方法-在DOM加载和保存(DOM Load and Save)模块中定义,新增了验证文档的方法,--在DOM验证(DOM Validation)模块中定义。
其他DOM标准:下面的语言是基于XML的:
- svg
- MathML
- SMIL
DOM是针对HTML和XML文档的一个API(应用程序编程接口)。
节点层次
DOM可以将任何HTML或XML文档描绘成,一个由多层次构成的结构。
节点分为几种不同的类型,每种类型分别表示文档中不同的信息及标记。每个节点拥有各自的特点、数据、方法另外与其他节点存在某种关系。
其中文档节点是每个文档的根节点,文档节点只有一个子节点,即<html>元素,称为文档元素。文档元素是文档的最外层元素,文档的其他元素都被包含在文档元素中,每个文档只有一个文档元素。在HTML中,文档元素是始终是<html>元素,在XML内,没有预定于元素,因此任何元素都可能称为文档元素。
每一个标记都可以通过树中的一个节点表示:HTML通过元素节点表示,特性(attribute)通过特性节点表示,文档类型通过文档类型节点表示,而注释通过注释节点表示。总共有12种节点类型,这些类型都继承自一个基类型。
节点类型
节点通过定义数值常量和字符常量表示,ie只支持数值常量。
主要的接口有
-
Node接口:它是文档中节点的基类型。定义了基本的访问和改变文档结构的方法。
- Element接口:常用于表示XML或HTML元素,提供了对元素标签名、子节点、及特性的访问。元素节点是唯一拥有属性的节点类型。
-
Document接口:它代表整个文档。可创建文档中的各种节点(元素、注释、处理指令等),是上图中的Document节点。创建的节点中带有一个OwnerDoculnent属性表示创建它们的Document对象。
-
DocumentFragment接口:它代表文档树的子树,相当一个小型文档。文档片段,等于占位符。
-
Attr接口:它代表元素节点的属性。有意思的是它并不认为是该元素节点的子节点,不构成DOM树的一部分。同时也不是DocumentFragment节点的直接子节点。
-
Text接口:它从CharacterData继承而来。代表元素或属性的一段连续的文本内容。文本下的空白区域也属于文本节点。它有一个派生的接口CDATAsection,目的是:CDATASeciton节点的内容将不会作任何转化;使用Node中的nomraliez方法时相邻的Text节点会合并成一个节点,但使用CDATASeciton可避免合并。
-
Comment接口:它也从CharacterData继承而来。代表注释中的文本内容。
-
DocuementType节点:每一个document都有一个documentType属性,它的值为document或者docuementType对象。
NodeName和NodeValue
在判断节点类型时,通过数值常量来判断的话,是兼容所有浏览器的(ie不支持字符常量)。
节点类型测试:
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>Sample Page</title>
</head>
<body>
<!--nodeName NodeValue实验-->
<div id="container">这是一个元素节点</div>
<script type="text/javascript">
var divNode = document.getElementById("container");
console.log(divNode.nodeName + "/"+ divNode.nodeValue);
var attrNode = divNode.attributes[0];
console.log(attrNode.nodeName + "/"+ attrNode.nodeValue);
var textNode = divNode.childNodes[0];
console.log(textNode.nodeName + "/"+ textNode.nodeValue);
// document.body.childNodes[0]是body标签后的空白位置
var commentNode = document.body.childNodes[1];
console.log(commentNode.nodeName + "/"+ commentNode.nodeValue);
// doctype节点
console.log(document.doctype.nodeName + "/"+document.doctype.nodeValue);
//
// 文档片段节点
var frag = document.createDocumentFragment();
console.log(frag.nodeName + "/" + frag.nodeValue);
</script>
</body>
</html>
运行结果:
DomReady
html标签和dom节点的区别:
HTML是一种标记语言,它告诉我们这里面有什么内容,但行为交互是需要通过dom操作来实现的。html标签是需要通过浏览器解析才会变成dom的,当传入一个url开始加载页面时,在这期间就是一个dom节点构建的过程。节点是以树的形式组织的,当页面的所有html标签都转化为节点以后,我们称dom树构建完毕,简称为domReady。
如何将html标签解析变为dom节点呢?
浏览器是通过渲染引擎实现的,渲染引擎的职责就是将浏览器的内容显示到屏幕上。正常情况下,渲染引擎可以实现HTML、
XML及图片。也可以通过插件显示其他内容。
浏览器渲染引擎的基本渲染流程
渲染:浏览器将html的内容显示出来的过程。
渲染引擎首先通过网络获得所请求文档的内容。
下图为html结构的渲染过程:
渲染引擎构建,并将标签转化为内容树。
解析样式信息,是解析标签内的样式信息及css样式。渲染树由包含各种属性的矩形组成。
布局渲染树:确定每个节点在屏幕上的确定坐标。
绘制渲染树:绘制dom节点,遍历渲染树,绘制每个节点。
外部资源加载:解析图片、脚本、iframe。
webkit主要渲染过程:
详细的浏览器渲染过程可查看:https://kb.cnblogs.com/page/129756/
浏览器是从上到下,从左到右来渲染html元素的。
window.onload与$(document).ready()
window.onload:是在页面上的东西(如外部样式,及图片等)后加载完成,然后才加载js的;
$(document).ready()是在dom树绘制完毕后,便加载js;
window.onload = function(){
alert("load");
}
// jq的domready方法
$(document).ready(function(){
alert("ready");
})
可以最直观地看到:$(document).ready() 更快一些。
一般使用window.load进行操作,防止在dom树还未创建完便挂载事件,导致报错。
但是有的情况提前挂载事件,如克隆检测、事件绑定、dom操作等。$(document).ready()也可以满足用户提前绑定事件的需求。
DOMReady的实现策略:
实现domReady:
function myReady(fn){
// 对于现代浏览器,对于DOMContentLoaded事件的处理采用标准的事件绑定方式
if(document.addEventListener){
document.addEventListener("DOMContentLoaded",fn, false); //实现侦测domReady事件
}else{
IEContentLoaded(fn);
}
//IE模拟DOMContentLoaded
function IEContentLoaded(fn){
var done = false;
// 只执行一次用户的回调函数init()
var init = function(){
if(!done){
done = true;
fn();
}
};
// 立即执行函数
(function(){
try{
// DOM树未创建完之前调用doScoll会抛出错误
d.documentElement.doScroll('left');
}catch(e){
// 延迟再试一次
setTimeout(arguments.callee, 50);
return;
}
// 没有错误就表示dom树创建完毕,然后立马执行用户回调
init();
})();
//监听document的加载状态
d.onreadystatechange = function(){
// 如果用户是在domReady之后绑定的函数,就立即执行
if(d.readyState == 'complete'){
d.onreadystatechange = null;
init();
}
}
}
}
使用:
myReady(function(){
alert("myReady");
});
查看各大框架domReady实现可查看:https://www.cnblogs.com/JulyZhang/achive/2011/02/12/1952484.html
为了提高用户体验,大多数情况下使用domReady。
HTML嵌套规则
为什么?
块元素与内联元素的嵌套规则:
1.块元素可以包含内联元素和其他块元素,但内联元素不能包含块元素,只能包含其他元素。
等还有很多。
dl、dt、dd
上一篇: CSS3——文字与文本
推荐阅读
-
JS--dom对象:document object model文档对象模型
-
什么是DOM(Document Object Model)文档对象模型
-
JavaScript学习总结(一) ECMAScript、BOM、DOM(核心、浏览器对象模型与文档对象模型)
-
了解文档对象模型DOM(Document Object Model)
-
JS--dom对象:document object model文档对象模型
-
DOM 文档对象模型、domReady、window.onload与$(document).ready()
-
JavaScript学习总结(一) ECMAScript、BOM、DOM(核心、浏览器对象模型与文档对象模型)
-
什么是DOM(Document Object Model)文档对象模型_DOM
-
XML中的树形结构与DOM文档对象模型的示例代码(图)
-
了解文档对象模型DOM(Document Object Model)