JavaScript DOM 总结(一)

DOM 是 Document Object Model(文档对象模型)的缩写。DOM 描绘了一个层次化的节点树,允许开发人员添加、移除和修改页面的某一部分。 HTML DOM 树形结构如下:

JavaScript DOM 总结(一)_第1张图片

DOM 可以将任何 HTML 或 XML 文档描绘成一个由多层节点构成的结构。节点分为几种不同的类型,每种类型分别表示文档中不同的信息及(或)标记。每个节点都拥有各自的特点、数据和方法,另外也与其他节点存在某种关系。

Node类型属性

DOM1 级定义了一个 Node 接口,该接口将由 DOM 中的所有节点类型实现。JavaScript 中的所有节点类型都继承自 Node 类型,因此所有节点类型都共享着相同的基本属性和方法。每个节点都有nodeType 、nodeName 和 nodeValue 属性。

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

要了解节点的具体信息,可以使用 nodeName 和 nodeValue 这两个属性。这两个属性的值完全取决于节点的类型。例如:元素节点的 nodeName 是标签名称,属性节点的 nodeName 是属性名称;对于文本节点,nodeValue 属性包含文本。对于属性节点,nodeValue 属性包含属性值。nodeValue 属性对于文档节点和元素节点是不可用的。


<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>nodeType nodeName nodeValue属性title>
head>
<body>
<div id="div1">div内文本div>

body>
<script type="text/javascript">

    var div = document.getElementById("div1");
    console.log(div.nodeType);  // 1
    console.log(div.nodeName);  // DIV
    console.log(div.nodeValue); // null

    var textNode = div.childNodes[0];     
    console.log(textNode.nodeType);  //3
    console.log(textNode.nodeName);  //#text
    console.log(textNode.nodeValue); //div内文本

script>
html>

上述代码创建了一个div元素节点,元素节点的nodeType为1,nodeName为对应的节点名称,nodeValue对元素节点不可用,因此为null。在div内还有一段文字,为文本节点,通过div.childNodes[0]可获得,文本节点的nodeType为3,nodeName永远是 #text,nodeValue 包含文本内容。

节点关系

HTML文档可以描述成HTML DOM树,那么DOM树中的节点彼此拥有层级关系。父(parent)、子(child)和同胞(sibling)等术语用于描述这些关系。父节点拥有子节点。同级的子节点被称为同胞(兄弟或姐妹)。节点之间的关系可以表述如下:

JavaScript DOM 总结(一)_第2张图片

与节点层次关系有关的属性

属性 含义
parentNode 获取该节点的父节点
childNodes 获取该节点的子节点数组
firstChild 获取该节点的第一个子节点
lastChild 获取该节点的最后一个子节点
nextSibling 获取该节点的下一个兄弟节点
previousSibling 获取该节点的上一个兄弟节点

为了解释上述属性的具体含义,下面通过具体代码实现。首先建立HTML文档如下:


<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>DOM树节点层次关系title>
head>
<body>
    <div id="father">
        <p id="child1">child1p>
        <p id="child2">child2p>
        <p id="child3">child3p>
    div>
body>
html>

1、parentNode

var father = document.getElementById("father");
var child1 = document.getElementById("child1");
var child2 = document.getElementById("child2");
var child3 = document.getElementById("child3");

console.log(child1.parentNode.nodeName);  //DIV
console.log(child1.parentNode===child2.parentNode);  // true

获取id为child1的p元素的parentNode为DIV,child2和child1的parentNode为同一个。

2、childNodes

    var nodelist = father.childNodes;
    console.log(nodelist.item(1).innerHTML); // child1
    console.log(nodelist[1].innerHTML);  // child1
    console.log(nodelist.length);  // 7

上述代码获取div的childNodes,其中保存着一个 NodeList 对象。 NodeList 是一种类数组对象,用于保存一组有序的节点,可以通过位置来访问这些节点。上述代码第二行和第三行描述了如何获取里面的节点,可以通过方括号,也可以使用 item()方法。并且可以通过.length来获取 NodeList 对象中有几个节点。

我们注意到div中只有三个P元素,为何通过.length得到的结果是7呢?这是因为我们在写HTML文档时存在换行空格,这些换行空格表示一个文本节点,我们可以通过for循环来遍历NodeList 对象中的每一个节点:

for (var i = 0; i < nodelist.length; i++) {
        // console.log(nodelist[i].nodeType);
        if (nodelist[i].nodeType==1) {
            console.log(nodelist[i].innerHTML);
        }else{
            console.log(nodelist[i].nodeType+":"+nodelist[i].nodeName+":("+nodelist[i].nodeValue+")");
        }
    }

在FireFox浏览器中得到的结果如下:

JavaScript DOM 总结(一)_第3张图片

3、firstChild

firstChild即获取某个节点的第一个子节点,要获取第一个子节点也可以通过someNode.childNodes[0]或someNode.childNodes.item(0)获取。

4、lastChild

lastChild即获取某个节点的最后一个子节点,要获取最后一个子节点也可以通过someNode.childNodes [someNode.childNodes.length-1]或者someNode.childNodes.item(someNode.childNodes.length-1)

5、nextSibling

nextSibling即获取该节点的下一个兄弟节点,同一兄弟级节点中最后一个节点的 nextSibling 属性的值为 null:

console.log(nodelist[0].nextSibling);  //  

console.log(child1.nextSibling); // console.log(nodelist[nodelist.length-1].nextSibling); // null

6、previousSibling

previousSibling即获取该节点的上一个兄弟节点,同一兄弟级节点中最后一个节点的 previousSibling属性的值同样为null:

console.log(nodelist[0].previousSibling); // null
console.log(child1.previousSibling); //
console.log(nodelist[nodelist.length-1].previousSibling); //  

另外, hasChildNodes()也是一个非常有用的方法,这个方法在节点包含一或多个子节点的情况下返回 true;当然,也可以通过childNodes的length 属性来判断是否存在子节点。

元素节点

但是大部分情况下,我们都是需要对元素节点进行操作,对应的元素节点的属性的如下:

属性 含义
children 所有子元素节点
childElementCount 子元素节点个数量
firstElementChild 第一个子元素节点
lastElementChild 最后一个子元素节点
nextElementSibling 下一个兄弟元素节点
previousElementSibling 前一个兄弟元素节点

上述的六个属性只包含元素节点,不包含文本节点,因此可以避免我们在程序中出现的换行空格被当做文本节点的情况,以下还是以上述的DOM结构来测试这六个元素节点属性。

var father = document.getElementById("father");
var child1 = document.getElementById("child1");
var child2 = document.getElementById("child2");
var child3 = document.getElementById("child3");

var childrenlist = father.children;
console.log(childrenlist.length); // 3
console.log(father.childElementCount);  // 3
console.log(childrenlist[1]);  // 

"child2"> console.log(father.firstElementChild); //

"child1"> console.log(father.lastElementChild); //

"child3"> console.log(child1.nextElementSibling); //

"child2"> console.log(child1.previousElementSibling); // null console.log(child3.nextElementSibling); // null console.log(child3.previousElementSibling); //

"child2">

你可能感兴趣的:(JavaScript)