DOM API详解
来源于:http://zxc0328.github.io/2016/01/23/learning-dom-part1/
https://zxc0328.github.io/2016/01/26/learning-dom-part2/
一、什么是DOM
Document Object Model(DOM)是用编程语言对HTML,XML以及SVG文档进行操作的接口。我们经常使用JavaScript来操纵DOM,不过DOM其实的语言无关的。它并不是JavaScript的一部分。
虽然如此,DOM在前端开发中经常和JS一起讨论,并且对JS造成了极大的负面影响。这个原因就在于早年间各大浏览器厂商(主要是老版本IE),对DOM的实现并没有按W3C的标准来做,而是自己制定了一套接口,由此给前端开发造成了极大的麻烦。我们需要使用jQuery这样的基础库,使用封装好的跨平台兼容API,才能使代码兼容主要浏览器。
直到今天,jQuery这样的基础库依然是不可或缺的。好消息是,随着时代的进步,DOM API的兼容性在主流浏览器中已经不是问题。在没有低版本IE的移动端web中,我们就可以不用为这个问题劳神了。
然而相比于CSS和JS所拥有的明确版本迭代和丰富的文档,DOM无论是在版本的碎片化程度还是文档的数量上来说都很难和前两者相比。
打开MDN的DOM文档首页,我们可以看到密密麻麻的API列表,点开其中的一个,可以看到更多的子API。其中除了DOM Core,有CSS DOM,还有HTMl5相关的DOM,更有Worker这样的浏览器相关的接口。可谓是一个大杂烩,CSS,JS,浏览器各种功能的API都在其中。因此本文就是一个DOM API的分类梳理,带大家看清DOM众多API的组成和层级。
二、DOM标准
我们从W3C的DOM Technical Reports来看,Document Object Model (DOM)目前有Level 1,Level 2,Level 3,以及Level4三个标准。每一个Level的标准下又分为多个模块,其中DOM2 Core Specification的发布时间为2000-11-13,而DOM3 Core Specification的发布时间为2004-04-07,最新的DOM4发布于2015-11-19。
DOM2由许多个标准组成是,如图:
然后我们来看看DOM3。DOM3标准构建在DOM2的基础上,因此数量上少于DOM2的模块。DOM3中的XPath Specification等等标准还没有正式成为推荐标准,因此没有加入图表。
三、DOM2与DOM3,以及非核心API
和CSS标准一样,DOM标准的版本也是各自独立的。我们所说的DOM2,DOM3其实主要指DOM Core Specification的版本。在DOM Core Specification中会写明这个版本的DOM Core和哪些版本的标准一起组成新一代DOM标准。
因此我们也就可以解释为什么DOM3的组成标准要大大少于DOM2了。DOM2中的Style Specification后来发展为了一个新的CSSOM Specification,事实上这个标准已经不属于DOM的范畴,而被划入CSS标准。而Events Specification的Level 3最后发展为了新的UI Events Specification以及Touch Events Specification等等独立的Event Specification,补充了DOM2 Events Specification中缺失的事件。Traversal and Range Specification中的Traversal部分发展为了新的Element Traversal Specification。
具体标准之间的关系可以看下表:
然后我们来看看所谓的非核心API。所谓的非核心API就是那些在W3C标准中不属于DOM的API,但是这些API和DOM的核心部分有着或多或少的关系。如CSS相关的CSSOM Specification,Selectors API等等。以及与HTML5相关的众多JavaScript API,比如Web Storage,Web Workers等等
本文关注的主要是DOM2,DOM3以及部分新模块的API,解读它们的构成,以及在浏览器的兼容情况。
四、API详解-DOM CORE
DOM标准的层级
DOM标准实际由很多的子模块组成,包括Core module,XML module,Events module,User interface Events module,Mouse Events module,Text Events module,Keyboard Events module,Mutation Events module,Mutation name Events module,HTML Events module,Load and Save module,Asynchronous load module,Validation module,和XPath module。
具体的层级结构如下图所示:
image credit: w3.org
DOM Core-导语
在我们把目光转向DOM Core模块之前,我想先讲讲如何阅读DOM的W3C Specification。首先我们可以阅读官方的导语-What is the Document Object Model?。
这一节中介绍了DOM的相关概念。比如关于DOM的结构,我们通常认为是一颗树,但实际上用森林来形容更为贴切,因为虽然以Document
为根节点的文档树最多只能有一颗,但我们还有一颗可选的doctype
节点树,以及comments
节点等等。
更重要的是,导语中还介绍了接下来文档中的一些惯例。比如因为DOM是独立于编程语言的,所以在文档中使用了IDL(Interactive Data Language)来描述接口。然后我们需要注意的一点就是,DOM可以用于HTML和XML,因此在前端同学看来,DOM中会有一些不太熟悉的概念,比如Namespace
和DOM URIs
,这些正是为了兼容XML而加入到DOM中的特性。不用过分在意。
下面是一个简化的IDL示例:
interface Element : Node {
readonly attribute DOMString tagName;
void removeAttribute(in DOMString name)
raises(DOMException);
Attr getAttributeNode(in DOMString name);
NodeList getElementsByTagName(in DOMString name);
};
IDL中主要描述了一个接口的继承关系,以及接口的方法和属性,及相应的参数和返回值
下面我们首先来看DOM Core模块。从“Core”这个名词就可以看出这个模块在整个DOM标准中处于中心地位。DOM Core模块主要定义了DOM最关键的一组接口和对象。其中最顶层的一个接口就是Node
。直接继承Node
的接口有Element
、DocumentType
、Attr
、ProcessingInstruction
、Comment
、Text
、CDATASection
和Notation
。
Node接口
Node
接口是整个DOM中最顶层的接口,DOM中的每一个节点都是一个Node
。从Node
接口分化出其他的更具体的接口。
Node
接口的属性:
属性名 | 返回值 | 备注 |
---|---|---|
nodeName | DOMString | 只读 |
nodeValue | DOMString | 只读 |
nodeType | unsigned short | 只读 |
parentNode | Node | 只读 |
childNodes | NodeList | 只读 |
firstChild | Node | 只读 |
lastChild | Node | 只读 |
previousSibling | Node | 只读 |
nextSibling | Node | 只读 |
attributes | NamedNodeMap | 只读 |
ownerDocument | Document | 只读 |
值得注意的是,虽然这些属性都定义在Node接口上,但是不是所有的底层接口实现都有对应的值。如Text
和Comment
节点都没有子元素,因此它们的childNodes
为null
。同理,Element
接口的nodeValue
值就为null
。
nodeType
属性的值被定义为一组常量:
// NodeType
const unsigned short ELEMENT_NODE = 1;
const unsigned short ATTRIBUTE_NODE = 2;
const unsigned short TEXT_NODE = 3;
const unsigned short CDATA_SECTION_NODE = 4;
const unsigned short ENTITY_REFERENCE_NODE = 5;
const unsigned short ENTITY_NODE = 6;
const unsigned short PROCESSING_INSTRUCTION_NODE = 7;
const unsigned short COMMENT_NODE = 8;
const unsigned short DOCUMENT_NODE = 9;
const unsigned short DOCUMENT_TYPE_NODE = 10;
const unsigned short DOCUMENT_FRAGMENT_NODE = 11;
const unsigned short NOTATION_NODE = 12;
这就是我们平时用来检测节点类型时使用的数值了。
下面从Node
接口的方法中选几个主流的API进行简单的介绍,对于W3C中为标准但在WHATWG中被废弃的,这里不进行介绍(在主流的浏览器中也没有相应的实现)。对于一些在继承Node的接口中有更具体实现的API,这里也不进行介绍(如hasAttributes
在Element接口中有更具体的实现)。
compareDocumentPosition
这是DOM3中引入的一个很有意思的API。这个API将两个Node的位置进行比较,然后返回
DocumentPosition
这组常量中的一种。这组常量是:// 节点被另一个节点包含。被包含的节点是父节点的后继
DOCUMENT_POSITION_CONTAINED_BY
// 节点包含另一个节点。父节点是子节点的前驱
DOCUMENT_POSITION_CONTAINS
DOCUMENT_POSITION_DISCONNECTED
// 后继关系
DOCUMENT_POSITION_FOLLOWING
DOCUMENT_POSITION_IMPLEMENTATION_SPECIFIC
// 前驱关系
DOCUMENT_POSITION_PRECEDING
appendChild
&&removeChild
这两个API是比较常用的,
appendChild
在DOM子元素列表的最后插入元素,如果这个元素已经存在DOM树中,就先移除这个元素再插入。removeChild
则从DOM子元素列表中移除元素。insertBefore
这个API有两个参数,一个是
newChild
,一个是refChild
。newChild
既是要插入的节点,而refChild
则是一个已经在Node
所在DOM树中的参考子节点。newChild
会插入到refChild
之前,如果refChild
是null
,那么newChild
会插入到Node
子节点列表的末尾。这个API的记忆很简单,命名是
insertBefore
,必然是有一个参考节点的,不然插到谁的前面去呢?isEqualNode
这个API的作用是判断两个DOM是否相等。这里的相等并不是指指向同一个对象,而是指属性和值方面是否相同。
对于两个节点来说比较的算法如下:
- 两个节点是否是相同的类型
nodeName, localName, namespaceURI, prefix, nodeValue
这些属性是否相同- 节点的属性集合(在DOM中的数据类型是
NamedNodeMaps
)是否相同,这里集合中属性的顺序可以是随意的 - 子节点集合(
NodeLists
类型)是否相同,这里会考虑节点的index,如果不一样则不相同。
Element接口
Document接口
Attr接口
Text,Comment和CharacterData接口
DOM中的基础数据类型
DOMString
DOMTimeStamp
DOMUserData
DOMObject
DOM API详解的更多相关文章
- jqGrid APi 详解
jqGrid APi 详解 jqGrid皮肤 从3.5版本开始,jqGrid完全支持jquery UI的theme.我们可以从http://jqueryui.com/themeroller/下载我们所 ...
- 百度地图API详解之事件机制,function“闭包”解决for循环和监听器冲突的问题:
原文:百度地图API详解之事件机制,function"闭包"解决for循环和监听器冲突的问题: 百度地图API详解之事件机制 2011年07月26日 星期二 下午 04:06 和D ...
- [转]百度地图API详解之地图坐标系统
博客原文地址:http://www.jiazhengblog.com/blog/2011/07/02/289/ 我们都知道地球是圆的,电脑显示器是平的,要想让位于球面的形状显示在平面的显示器上就必然需 ...
- canvas绘图API详解
canvas绘图API详解 1.context的状态 矩阵变换属性 当前剪辑区域 context的其他状态属性: strokeStyle, fillStyle, globalAlpha, lineWi ...
- Java 8 Stream API详解--转
原文地址:http://blog.csdn.net/chszs/article/details/47038607 Java 8 Stream API详解 一.Stream API介绍 Java8引入了 ...
- hibernate学习(2)——api详解对象
1 Configuration 配置对象 /详解Configuration对象 public class Configuration_test { @Test //Configuration 用户 ...
- 网络编程socket基本API详解(转)
网络编程socket基本API详解 socket socket是在应用层和传输层之间的一个抽象层,它把TCP/IP层复杂的操作抽象为几个简单的接口供应用层调用已实现进程在网络中通信. socket ...
- dom对象详解--document对象(二)
dom对象详解--style对象 style对象 style对象和document对象下的集合对象styleSheets有关系,styleSheets是文档中所有style对象的集合,这里讲解的 ...
- dom对象详解--document对象(一)
document对象 Document对象代表整个html文档,可用来访问页面中的所有元素,是最复杂的一个dom对象,可以说是学习好dom编程的关键所在. Document对象是window对象的一 ...
随机推荐
- Python json模块dumps loads
python中json数据的使用. dumps和loads也是需要成对使用的,就像c++ new/delete malloc/free一样需要成对使用. 看着像json的字符串,也不一定是json字符 ...
- go语言之进阶篇WriteString的使用
1.WriteString的使用 示例: package main import ( "fmt" "os" ) func WriteFile(path stri ...
- CSS-设置Footer始终在页面底部
Footer顾名思义页脚,如果内容多的时候在底部时感官很好,但是当内容变少(无法撑开一屏的时候)footer不固定在底部,影响美观,对于已经从事前端工作的工作的来说应该是比价工作中入门级别的问题了,由 ...
- JS弹出层遮罩,隐藏背景页面滚动条细节优化
做过弹层组件的童鞋应该都考虑过特殊情况下取消页面滚动条,让其不能滚动,这样用户体验会好很多,当弹层内容超出屏幕展现范围的时候在弹层上面增加滚动条来查看全部内容. 一.去除滚动条方法给body添加ove ...
- JAVA-找不到元素 'beans' 的声明
问题: Tomcat启动时,spring加载配置文件applicationContext.xml出错,抛出nested exception is og.xml.sax.SAXParseExceptio ...
- 红米除线刷的另外一种救砖方法fastboot
原文来自:https://jingyan.baidu.com/article/48a42057e945bca9242504d7.html , 按照它操做了一下,虽然没有救活我的红米1,但是让我更好的了 ...
- codeforces 551 C GukiZ hates Boxes
--睡太晚了. ..脑子就傻了-- 这个题想的时候并没有想到该这样-- 题意大概是有n堆箱子从左往右依次排列,每堆ai个箱子,有m个人,最開始都站在第一个箱子的左边, 每个人在每一秒钟都必须做出两种选 ...
- LintCode:Fibonacci
C++ class Solution{ public: /** * @param n: an integer * @return an integer f(n) */ int fibonacci(in ...
- git 保存用户名密码
打开本地的.git/config 加入 [credential] helper = store 保存,第一次需要输入用户名密码,输入一次密码后第二次就会记住密码了不会再提示输入用户名及密码
- Linux中Sed的用法
Linux中Sed的用法 sed是一个很好的文件处理工具,本身是一个管道命令,主要是以行为单位进行处理,可以将数据行进行替换.删除.新增.选取等特定工作,下面先了解一下sed的用法sed命令行格式为: ...