DOM之节点层级-Node类型

 一  Node类型

出现版本:DOM Level 1

Node 接口 在 JavaScript中被实现为 Node 类型,在除 IE之外的所有浏览器中都可以直接访问这个类型。

在 JavaScript 中,所有节点类型都继承 Node 类型,因此所有类型都共享相同的基本属性和方法

二  公共属性

在 JavaScript 中,所有节点类型都继承 Node 类型,因此所有类型都共享相同的基本属性和方法

  • 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)

程序实现:节点类型可通过与这些常量比较来确定

if (someNode.nodeType == Node.ELEMENT_NODE){ 
 alert("Node is an element."); 
}
  • nodeName属性
  • nodeValue属性
    • nodeName 与 nodeValue 保存着有关节点的信息
    • 这两个属性的值完全取决于节点类型。
    • 在使用 这两个属性前,最好先检测节点类型
       
      if (someNode.nodeType == 1){ 
          value = someNode.nodeName; // 会显示元素的标签名 
      } 
      
      //在这个例子中,先检查了节点是不是元素。
      //如果是,则将其 nodeName 的值赋给一个变量。
      //对元素 而言,nodeName 始终等于元素的标签名,而 nodeValue 则始终为 null。

三 节点关系

  • 节点:Node
    • 属性:
      • childNodes -> NodeList实例
      • ownerDocument:一个指向代表整个文档的文档节点的指针
        • 所有节点都被创建它们(或自己所在)的文档所拥有
    • 获取节点长度:length
      let count = someNode.childNodes.length; 
    • 判断是否存在某节点:hasChildNodes()
      • 返回true:说明节点有一个或多个子节点
    • 访问节点元素:
      • 中括号[]
        let firstChild = someNode.childNodes[0]; 
        
      • 使用item()方法
        let secondChild = someNode.childNodes.item(1); 
        
    • 将NodeList对象转换为数组
      • Array.prototype.slice()
        let arrayOfNodes = Array.prototype.slice.call(someNode.childNodes,0);
      • Array.from()
        let arrayOfNodes = Array.from(someNode.childNodes); 
  • 父节点: parentNode
  • 关系:
    • 第一个子节点:firstChild / xxx.childNodes[0]
    • 最后一个子节点:lastChild / xxx.childNodes[xxx.childNodes.length -1 ]
    • 同胞节点:使用previousSibling nextSibling在列表的节点间导航
      • 第一个节点的previousSibling属性为null
      • 最后一个节点的nextSibling属性为null
      • childNodes中只有一个节点,则previousSibling和nextSibling属性为null
        if (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."); 
        } 

四 操作节点

  1. appendChild()、insertBefore():在插入节点时不会删除任何已有节点
  2. replaceChild()、removeChild():被移除的节点从技术上说仍然被同一个文档所拥有,但文档中已经没有它的位置
  • appendChild():用于在childNodes末尾添加节点
    • 原理:添加新节点会更新相关的关系指针,包括父节点和之前的最后一个子节点,DOM树通过各种关系指针微信,一个节点也不会在文档中同时出现在两个或更多个地方
    • 返回值:返回新添加的节点
    • 使用场景:添加未存在的新节点  /  将已存在的节点转移到新位置
// appendChild()方法返回新添加的节点

let returnedNode = someNode.appendChild(newNode); 
alert(returnedNode == newNode); // true 
alert(someNode.lastChild == newNode); // true


// 假设 someNode 有多个子节点

let returnedNode = someNode.appendChild(someNode.firstChild); 
alert(returnedNode == someNode.firstChild); // false 
alert(returnedNode == someNode.lastChild); // true

  • insertBefore():用于在childNodes的特定位置添加节点
    • 参数:(2个)要插入的节点  参照节点
    • 原理:要插入的节点会变成参照节点的前一个同胞节点,并被返回
// 如果参照节点是 null,则 insertBefore()与 appendChild()效果相同,如下面的例子所示:
// 作为最后一个子节点插入
returnedNode = someNode.insertBefore(newNode, null); 
alert(newNode == someNode.lastChild); // true 

// 作为新的第一个子节点插入
returnedNode = someNode.insertBefore(newNode, someNode.firstChild); 
alert(returnedNode == newNode); // true 
alert(newNode == someNode.firstChild); // true 

// 插入最后一个子节点前面
returnedNode = someNode.insertBefore(newNode, someNode.lastChild); 
alert(newNode == someNode.childNodes[someNode.childNodes.length - 2]); // true

  • replaceChild():替换节点
    • 参数:(2个)要插入的节点  要替换的节点
    • 返回:要替换的节点会被返回并从文档树中完全移除;要插入的节点会取而代之
    • 原理:插入一个节点后,所有关系指针都会从被替换的节点复制过来
// 替换第一个子节点
let returnedNode = someNode.replaceChild(newNode, someNode.firstChild); 
// 替换最后一个子节点
returnedNode = someNode.replaceChild(newNode, someNode.lastChild);

  • removeChild():移除节点
    • 参数:要移除的节点
    • 返回:被移除的节点会被返回
// 删除第一个子节点
let formerFirstChild = someNode.removeChild(someNode.firstChild); 
// 删除最后一个子节点
let formerLastChild = someNode.removeChild(someNode.lastChild);

五 其他方法

  • cloneNode()
    • 参数:一个布尔值参数,表示是否深复制
      • 深复制:传入true,即复制节点及其整个子 DOM 树
      • 浅复制:传入false,则只会复制调用该方法的节点
    • 返回:返回与调用它的节点一模一样的节点

孤儿节点(orphan):复制返回的节点属 于文档所有,但尚未指定父节点

可以通过 appendChild()、 insertBefore()或 replaceChild()方法把孤儿节点添加到文档中

<ul> 
 <li>item 1</li> 
 <li>item 2</li> 
 <li>item 3</li> 
</ul> 
// deepList 保存着 myList 的副本。这意味着 deepList 有 3 个列表项,每个列表
项又各自包含文本

let deepList = myList.cloneNode(true); 
alert(deepList.childNodes.length); // 3(IE9 之前的版本)或 7(其他浏览器)

// shallowList 则保存着 myList 的浅副本,因此没有子节点

let shallowList = myList.cloneNode(false); 
alert(shallowList.childNodes.length); // 0 


// deepList.childNodes.length 的值会因 IE8 及更低版本和其他浏览器对空格的处理方式而不同。IE9之前的版本不会为空格创建节点。

cloneNode()方法不会复制添加到 DOM 节点的 JavaScript 属性,比如事件处理程序。

这个方法只复制 HTML 属性,以及可选地复制子节点。除此之外则一概不会复制。

  • normalize()
    • 作用:处理文档子树中的文本节点
    • 操作:会检测这个节点的所有后代
      • 不包含文本的文本节点 或 文本节点之间互为同胞关系
    • 返回:
      • 有空文本节点,将其删除
      • 两个同胞节点是相邻的,则将其合并为一个文本节点

猜你喜欢

转载自blog.csdn.net/xiaoyangzhu/article/details/121765281