JavaScript学习笔记——DOM类型(Node类型)
Node类型
- DOMLevel 1描述了名为Node的接口,这个接口时所有DOM节点类型都必须实现的。
- 每个节点都有nodeType 属性,表示该节点的类型。节点类型由定义在 Node类型上的12个数值常量表示:
- Node.ELEMENT_NODE(1)
- Node.ATTRIBUTE_NODE(2)
- Node.TEXT_NODE(3)
- Node.CDATA_SECTION_NODE(4)
- Node.ENTITY_REFERENCE_NODE(5)
- Node.ENTITY_NODE(6)
- Node.PROCESSING_INSTRUCTION_NODE(7)
- Node.COMMENT_NODE(8)
- Node.DOCUMENT_NODE(9)
- Node.DOCUMENT_TYPE_NODE(10)
- Node.DOCUMENT_FRAGMENT_NODE(11)
- Node.NOTATION_NODE(12)
1、nodeName与nodeValue
- nodeName 与nodeValue 保存着有关节点的信息。
- 这两个属性的值完全取决于节点类型,在使用这两个属性前,最好先检测节点类型。
1 | if (someNode.nodeType == 1){ |
2、节点关系
- 文档中的所有节点都与其他节点有关系,这些关系可以形容为家族关系,相当于把文档树比作家谱。
- 每个节点都有一个childNodes属性,其中包含一个NodeList的实例。
- NodeList是一个类数组对象,用于存储可以按位置存取的有序节点。
- NodeList并不是Array的实例,但可以使用中括号访问它的值,而且它也有length属性。
- NodeList是一个对DOM结构的查询,DOM结构的变化会自动地在NodeList 中反映出来。
- 我们通常说NodeList 是实时的活动对象,而不是第一次访问时所获得内容的快照。
1 | let firstChild = someNode.childNodes[0]; |
- 使用Array.prototype.slice()可以把NodeList对象转换为数组。
- ES6的Array.from()静态方法同样也能实现。
1 | let arrayOfNodes1 = Array.prototype.slice.call(someNode.childNodes,0); |
每个节点都有一个parentNode属性,指向其DOM树中的父元素。
childNodes中的所有节点都有同一个父元素,因此它们的parentNode属性都指向同一个节点。
childNodes列表中的每个节点都是同一列表中其他节点的同胞节点。
使用previoussibling 和nextsibling可以在这个列表的节点间导航。
这个列表中第一个节点的previoussibling属性是 null,最后一个节点的nextSibling属性也是null。
1
2
3
4
5if (someNode.nextSibling === null){
alert("Last node in the parent's childNodes list.");
} else if (someNode.previousSibling === null){
alert("First node in the parent's childNodes list.");
}如果childlNodes中只有一个节点,则它的previoussibling和 nextsibling 属性都是null。
父节点和它的第一个及最后一个子节点也有专门属性:firstchild 和 lastchild 分别指向childNodes 中的第一个和最后一个子节点。
someNode.firstchild的值始终等于someNode.childNodes[0],而someNode.lastChild 的值始终等于someNode.childNodes[someNode.childNodes.length-1]。
如果只有一个子节点,则firstchild和 lastchild指向同一个节点。
如果没有子节点,则firstchild和 lastchild都是 null。
3、操纵节点
- 由于所有的关系指针都是只读的,DOM提供了一些操纵节点的方法。
- appendChild():用于在childNodes列表末尾添加节点
- 添加新节点会更新相关的关系指针,包括父节点和之前一个子节点。
- appendChild()会返回新添加的节点。
1 | let returnedNode = someNode.appendChild(newNode); |
- 如果把文档中已经存在的节点传给appendChild() ,则这个节点会从之前的位置被转移到新位置。
- 即使DOM树通过各种关系指针维系,一个节点也不会在文档中同时出现在两个或更多个地方。
- 如果调用appendChild()传入父元素的第一个子节点,则这个节点会成为父元素的最后一个子节点。
1 | // 假设 someNode 有多个子节点 |
- 如果想把节点放到childNodes中的特定位置而不是末尾,则可以使用**insertBefore()**方法。
- 方法接收两个参数:要插入的节点和参照节点。
- 调用这个方法后,要插入的节点会变成参照节点的前一个同胞节点,并被返回。
- 如果参照节点是 null,则insertBefore()与 appendchild()效果相同。
1 | // 作为最后一个子节点插入 |
- appendChild()和insertBefore()在插入节点时不会删除任何已有节点。
- replacechild()方法接收两个参数:要插入的节点和要替换的节点。
- 要替换的节点会被返回并从文档树中完全移除,要插入的节点会取而代之。
- 使用replacechild()插入一个节点后,所有关系指针都会从被替换的节点复制过来。
1 | // 替换第一个子节点 |
- 移除节点可以使用removeChild()方法。
- 这个方法接收一个参数,即要移除的节点。
- 被移除的节点会被返回,
1 | // 删除第一个子节点 |
- 上面介绍的4个方法都用于操纵某个节点的子元素,也就是说使用它们之前必须先取得父节点(使用前面介绍的parentNode属性)。
- 并非所有节点类型都有子节点,如果在不支持子节点的节点上调用这些方法,则会导致抛出错误。
4、其他方法
cloneNode()会返回与调用它的节点一模一样的节点。
- 方法接收一个布尔值参数,表示是否深复制。即复制节点及其整个子DOM树。
- 如果传入 false,则只会复制调用该方法的节点。
- 复制返回的节点属于文档所有,但尚未指定父节点,所以可称为孤儿节点 ( orphan )。
- 可以通过appendchild(),insertBefore()或replacechild()方法把孤儿节点添加到文档中。
normalize()用于处理文档子树中的文本节点。
- 在节点上调用normalize()方法会检测这个节点的所有后代,从中搜索上述两种情形。
- 如果发现空文本节点,则将其删除;
- 如果两个同胞节点是相邻的,则将其合并为一个文本节点。
本博客所有文章除特别声明外,均采用 CC BY-NC-SA 4.0 许可协议。转载请注明来自 姚永坤的小窝!
评论