来源于: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

具体标准之间的关系可以看下表:

DOM2模块 新标准
Style Specification Level 2 CSSOM Specification(Not a part of DOM now)
Traversal and Range Specification Level 2 Element Traversal Specification(Part of DOM4)
Events Specification Level 2 UI Events Specification
Touch Events Specification
Pointer Events Specification
Progress Events Specification

然后我们来看看所谓的非核心API。所谓的非核心API就是那些在W3C标准中不属于DOM的API,但是这些API和DOM的核心部分有着或多或少的关系。如CSS相关的CSSOM SpecificationSelectors API等等。以及与HTML5相关的众多JavaScript API,比如Web StorageWeb 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中会有一些不太熟悉的概念,比如NamespaceDOM 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的接口有ElementDocumentType
AttrProcessingInstructionComment
TextCDATASectionNotation

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接口上,但是不是所有的底层接口实现都有对应的值。如TextComment节点都没有子元素,因此它们的childNodesnull。同理,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,一个是refChildnewChild既是要插入的节点,而refChild则是一个已经在Node所在DOM树中的参考子节点。newChild会插入到refChild之前,如果refChildnull,那么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详解的更多相关文章

  1. jqGrid APi 详解

    jqGrid APi 详解 jqGrid皮肤 从3.5版本开始,jqGrid完全支持jquery UI的theme.我们可以从http://jqueryui.com/themeroller/下载我们所 ...

  2. 百度地图API详解之事件机制,function“闭包”解决for循环和监听器冲突的问题:

    原文:百度地图API详解之事件机制,function"闭包"解决for循环和监听器冲突的问题: 百度地图API详解之事件机制 2011年07月26日 星期二 下午 04:06 和D ...

  3. [转]百度地图API详解之地图坐标系统

    博客原文地址:http://www.jiazhengblog.com/blog/2011/07/02/289/ 我们都知道地球是圆的,电脑显示器是平的,要想让位于球面的形状显示在平面的显示器上就必然需 ...

  4. canvas绘图API详解

    canvas绘图API详解 1.context的状态 矩阵变换属性 当前剪辑区域 context的其他状态属性: strokeStyle, fillStyle, globalAlpha, lineWi ...

  5. Java 8 Stream API详解--转

    原文地址:http://blog.csdn.net/chszs/article/details/47038607 Java 8 Stream API详解 一.Stream API介绍 Java8引入了 ...

  6. hibernate学习(2)——api详解对象

    1   Configuration 配置对象 /详解Configuration对象 public class Configuration_test { @Test //Configuration 用户 ...

  7. 网络编程socket基本API详解(转)

    网络编程socket基本API详解   socket socket是在应用层和传输层之间的一个抽象层,它把TCP/IP层复杂的操作抽象为几个简单的接口供应用层调用已实现进程在网络中通信. socket ...

  8. dom对象详解--document对象(二)

       dom对象详解--style对象 style对象 style对象和document对象下的集合对象styleSheets有关系,styleSheets是文档中所有style对象的集合,这里讲解的 ...

  9. dom对象详解--document对象(一)

     document对象 Document对象代表整个html文档,可用来访问页面中的所有元素,是最复杂的一个dom对象,可以说是学习好dom编程的关键所在. Document对象是window对象的一 ...

随机推荐

  1. qt.qpa.plugin: Could not find the Qt platform plugin "windows" in ""

    转载:https://forum.qt.io/topic/97484/qt-5-12-make-mingw-32-release/12 I build Qt 5.12 with MinGW 7.3.0 ...

  2. 卡卡游戏引擎之MVC模式下的事件处理

    前言 在前一篇文章 卡卡游戏引擎快速入门中提到了卡卡游戏引擎采用mvc的开发模式,这里相信介绍一下引擎在mvc模式下是如何做到低耦合的事件处理的. 在卡卡编辑器中选择一个节点,然后在左侧工具栏中切换到 ...

  3. HTML中的转义字符 (转)

    HTML中<, >,&等有特殊含义,(前两个字符用于链接签,&用于转义),不能直接使用.使用这三个字符时,应使用它们的转义序列,如下所示: & 或 & &a ...

  4. mybatis 乐观锁和逻辑删除

    本篇介绍easymybatis如配置乐观锁和逻辑删除. 乐观锁 easymybatis提供的乐观锁使用方式跟JPA一样,使用@Version注解来实现.即:数据库增加一个int或long类型字段ver ...

  5. Java中动态代理方式:

    JDK中生成代理对象的API 代理类所在包:java.lang.reflect.ProxyJDK实现代理只需要使用newProxyInstance方法,但是该方法需要接收三个参数,完整的写法是: st ...

  6. windows 查看动态连接库和静态连接库的方法

    在window下查看动态库的导出函数可以用vs自带的Dependenc工具: 查看静态库的信息要用命令行来实现: dumpbin   /LINKERMEMBER   Test.lib   >   ...

  7. 文字编码和Unicode

    文字编码和Unicode 说明文字: https://blog.csdn.net/fengzhishang2019/article/details/7859064 Java 程序: https://w ...

  8. 转:查看linux系统版本号

    转自: http://blog.csdn.net/zhuying_linux/article/details/6859286 lsb_release -a

  9. installers PHPManager

    === Verbose logging started: // :: Build type: SHIP UNICODE 5.00.10011.00 Calling process: C:\Progra ...

  10. Android学习之Android studio TraceView和lint工具的使用具体解释

    上次讲述了一下Android studio Terminal的使用配置,今天又学习了一下关于Traceview和lint工具的使用. 首先来讲lint吧: Android lint工具是Android ...