JavaScript红宝书12-DOM第二级和第三级(DOM Levels 2 and 3)

36 阅读6分钟

之前的第一级DOM主要是聚焦在HTML文件的底层结构,第二、三级DOM侧重在构建结构和用户交互,主要包含这些模块。

DOM Core:构建在第一级的核心,添加方法和属性到节点。

DOM Views:基于不同的样式信息,定义不同的视图在文件中。

DOM Events:解释如何绑定交互事件到DOM文件。

DOM Style:定义如何访问和改变CSS样式信息。

DOM Traversal and Range:遍历DOM文件。

DOM HTML:构建在第一级的HTML上,添加属性、方法和新的接口。

DOM Mutation Observers:允许定义回调函数去改变DOM。

DOM的改变

DOM的第二级和第三级的核心目的是为了:扩展DOM API包含所有XML的需求,并且提供更好的错误处理和属性检测。

最重要的部分是支持XML的命名空间,DOM 二级不会涉及新的类型,它只是增加了DOM一级的类型,包含新的属性和方法。

DOM 三级,进一步的增强已有的类型并引入新的类型。

DOM视图和HTML增强DOM接口,都是提供新的属性和方法,这两个模块都非常小,与核心模块一起研究,如何改变JavaScript基本对象。

XML 命名空间

XML 命名空间允许从不同的XML语言的元素混在同一个文件中,不用担心元素命名冲突。

注意:XML命名空间不支持HTML,但支持XHTML

改变节点

Node类型的进化是在 二级DOM中引入了命名空间具体属性,包括:

localName:节点名称不包含命名空间前缀

namespaceURI:节点命名空间URI

prefix:命名空间的前缀或者null

当一个节点使用命名空间前缀,那么nodeName就等于 prefix + ":" + localName

DOM三级进一步引入了命名空间相关的方法

isDefaultNamespace(namespaceURI):当指定的命namespaceURI是节点默认的命名空间,返回true

lookupNamespaceURI(prefix):返回给出前缀的namespace URI

lookupPrefix(namespaceURI):返回给定namespace URI的前缀

改变文件

在二级DOM中,Document类型改变引入以下有关命名空间的方法:

createElementNS(namespaceURI, tagName):给定tagName创建一个新元素,作为namespaceURI指向命名空间的一部分

createAttributeNS(namespaceURI, attributeName):创建一个新的属性节点,作为namespaceURI指向命名空间的一部分

getElementsByTagNameNS(namespaceURI, tagName):返回一个使用给定tagName的元素NodeList,也作为namespaceURI指向命名空间的一部分

改变元素

在二级DOM核心中改变元素是和属性最有关联:

getAttributeNS(namespaceURI, localName):从代表namespaceURI 和一个命名的 localName的命名空间中获取属性,

getAttributeNodeNS(namespaceURI, localName):从代表namespaceURI 和一个命名的 localName的命名空间获取属性节点

getElementsByTagNameNS(namespaceURI, tagName):返回一个使用给定tagName的元素NodeList,也作为namespaceURI指向命名空间的一部分。

样式

二级DOM样式提供了API,可以访问三种样式(行内、外部、style标签)

访问元素样式

任何HTML属性都支持style属性,都暴露style属性给JavaScript,style对象CSSStyleDeclaration的实例,包含所有HTML样式的信息,但不包含内联样式信息。

style指定任何CSS属性,作为style对象的属性。

由于CSS属性名使用横线的命名方式(dash case)如:background-image,必须在JavaScript使用时转为驼峰:style.backgroundImage。

DOM样式属性和方法

二级DOM的样式定义了下面的这些属性和方法可修改元素的样式

cssText:提供访问样式属性的CSS代码

length:元素应用的属性数量

parent:CSSRule对象表示CSS信息

getPropertyCSSValue(propertyName):返回一个包含给定属性值的CSSValue对象

getPropertyPriority(propertyName):如果属性设置了!important,则返回important字符串

getPropertyValue(propertyName):返回属性给定的字符串值

item(index):返回指定位置的CSS属性名

removeProperty(propertyName):移除给定的样式属性

setProperty(propertyName, value, priority):设置属性并设置值,同时设置优先级

遍历

二级DOM的Traversal 和 Range 模块定义了两个类型用于遍历模块,NodeIterator和TreeWalker,这两个类型都用于做深度优先遍历。

<!DOCTYPE html>
<html>
  <head>
    <title>Example</title>
  </head>
  <body>
    <p><b>Hello</b> world!</p>
  </body>
</html>

最基本的一段HTML代码,其深度优先遍历的结构树如下图所示

NodeIterator

NodeIterator是之前提到的两种类型比较简单的那个,创建实例可以通过document.createNodeIterator()方法进行创建,可以接收以下这4个参数:

root:项从树中什么位置的节点开始查找

whatToShow:指示应该访问节点的数字代码

filter:NodeFilter对象或者函数指示,这个节点,应该被拒绝还是接受

entityReferenceExpansion:一个布尔值指代实体引用是否应该扩张,不会影响HTML页面,因为实体引用永远不会扩张

NodeIterator主要有两个方法,nextNode()和previousNode(),nextNode()方法:通过深度优先的方式向下一个节点遍历DOM子树。previousNode()方法:遍历中向上一个

注意:nextNode()方法在遇到最后一个节点时会返回null,previousNode()方法在遇到根节点时会返回null

TreeWalker

与NodeIterator有相同的方法nextNode()和previousNode(),除此之外还有5个更高级的方法:

parentNode():遍历当到前节点的父节点

firstChild(): 遍历到当前节点的第一个子节点

lastChild(): 遍历到当前节点的最后一个子节点

nextSibling(): 遍历到当前节点的下一个兄弟节点

previousSibling(): 遍历到当前节点的上一个兄弟节点

创建TreeWalker对象通过document.createTreeWalker()方法,也可以接收4个参数与NodeIterator相同,主要区别是filter返回的内容不相同,TreeWalker的强大之处就在于可以查找各兄弟节点。

区间

区间的使用可以在文件中选择一段节点忽略,当要操作节点无法确定具体信息可以使用区间进行筛选要操作的节点。

DOM的区间

二级DOM在Document类型上被定义了个createRange()方法,这个方法是属于文件对象的,区间一但被创建就绑定了对应的文件,不能在别的文件中使用,一但区间被创建,可以对区间的内容执行大量的不同操作。

操作区间

startContainer:区间开始区域

startOffset:startContainer的内部偏移量

endContainer:区间结束区域

endOffset:endContainer的偏移

commonAncestorContainer:文件最深的节点,同时包含startContainer和endContainer

简单选择在DOM区间中

最简单选择文件一部分区间包括两个方法selectNode()和selectNodeContents(),这些方法接收一个参数,一个装满节点信息的DOM节点。

selectNode()方法:选择节点实体,以及他们的子节点

selectNodeContents()方法:只选择子节点

复杂选择在DOM区间中

setStart()和setEnd()方法接收两个参数:一个引用节点和偏移量,setStart()就传startContainer和startOffset,setEnd()方法就传endContainer和endOffset。