CH16-DOM元素增删改

本章目标

  • 掌握如何使用DOM获取节点时使用的属性
  • 熟练使用DOM节点进行创建、添加、删除、替换

一、使用DOM获取节点时使用的属性

1.1 首尾子节点

firstChild:获取当前节点的首个子节点,注意:换行符、空格等也是节点。

lastChild:访问当前节点的最后一个子节点,是 Node 对象。

注:lastChild 返回的是这些子节点:元素节点、文本节点或注释节点。元素之间的空白也是文本节点。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
<!DOCTYPE html>
<html lang="en">

<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
<script>

function test1(){
//获取首个子节点
var node=document.querySelector("#ul_1").firstChild;
alert(node.innerHTML);
}

function test2(){
//获取尾个子节点
var node=document.querySelector("#ul_1").lastChild;
alert(node.innerHTML);
}
</script>
</head>

<body>
<ul id="ul_1" class="abc">
<li>li-1</li>
<li>li-2</li>
<li id="li_3">li-3</li>
<li>li-4</li>
<li>li-5</li>
</ul>
<button onclick="test1()">获取首个子节点</button>
<button onclick="test2()">获取尾个子节点</button>


</body>

</html>

1.2 首尾元素子节点

firstElementChild :访问当前节点的首个元素子节点,是 Element对象。

lastElementChild :访问当前节点的尾个元素子节点,是 Element对象。

1
2
3
4
5
6
7
8
9
10
11
12
function test1(){
//获取首个元素子节点
var node=document.querySelector("#ul_1").firstElementChild;

alert(node.innerHTML);
}
function test2(){
//获取尾个元素子节点
var node=document.querySelector("#ul_1").lastElementChild;

alert(node.innerHTML);
}

1.3 兄弟节点

previousSibling:返回同一层级中指定节点的前一个节点,是 Node 对象。

previousSibling 属性是只读的。

如果没有 previousSibling 节点,则返回值是 null。

nextSibiling:返回同一层级中指定节点之后紧跟的节点,是Node对象

nextSibling 属性是只读的。

如果没有 nextSibiling节点,则返回值是 null。

1
2
3
4
5
6
function test3() {
var node1=document.querySelector("#li_3").previousSibling;
var node2=document.querySelector("#li_3").nextSibiling;
alert("上一个节点:"+node1.innerHTML);
alert("下一个节点:"+node2.innerHTML);
}

注:nextSibiling 返回下一个同胞节点:元素节点、文本节点或注释节点 。

previousElementSibling :返回同一层级中指定节点之前的元素节点,是Element对象

nextElementSibling :返回同一层级中指定节点之后的元素节点,是Element对象

1
2
3
4
5
6
function test4() {
var node1=document.querySelector("#li_3").previousElementSibling ;
var node2=document.querySelector("#li_3").nextElementSibling ;
alert("上一个元素节点:"+node1.innerHTML);
alert("下一个元素节点:"+node2.innerHTML);
}

1.4 父、子节点

parentNode:访问当前元素节点的父节点 如果指定的节点没有父节点则返回 null.

childNodes:当前节点的所有子节点 返回所有节点的数组,只返回文本和元素节点,对于属性节点直接无视

1
2
3
4
5
6
function test5(){

//获取父节点
var node=document.querySelector("#ul_1").parentNode;
alert(node.nodeName);
}
1
2
3
4
5
6
7
8
9
10
11
12
13
function test6(){

//获取子节点
var nodes=document.querySelector("#ul_1").childNodes; //调试观察各节点属性

for(var i=0;i<nodes.length;i++){

var node=nodes[i];

if(node.nodeType==3)continue;
alert(node.innerHTML);
}
}

1.4 节点属性

nodeName:节点的名称

nodeName 是只读的

元素节点的 nodeName 与标签名相同 ,属性节点的 nodeName 与属性名相同, 文本节点的 nodeName 始终是 #text ,文档节点的 nodeName 始终是 #document 。

1
2
3
4
5
6
7
8
9
10
11
12
function test7(){

//元素节点的nodeName
alert(document.querySelector("#ul_1").nodeName);

//属性节点的nodeName
var node= document.getElementById("ul_1").attributes["class"];
alert(node.nodeName);

//文本节点的nodeName
alert(document.querySelector("#li_3").firstChild.nodeValue);
}

注:nodeName 所包含的 XML 元素的标签名称永远是大写的

nodeValue:节点的值

元素节点的 nodeValue 是 undefined 或 null

文本节点的 nodeValue 是文本本身

属性节点的 nodeValue 是属性值

1
2
3
4
5
6
7
8
9
10
11
12
13
function test8(){

//元素节点的nodeValue
alert(document.querySelector("#ul_1").nodeValue);

//属性节点的nodeValue
var node= document.getElementById("ul_1").attributes["class"];
alert(node.nodeValue);

//文本节点的nodeValue
alert(document.querySelector("#li_3").firstChild.nodeValue);

}

注:nodeValue 属性对于文档节点和元素节点是不可用的。

nodeType:节点类型

​ 1:表示当前节点的类型是标签(元素)

​ 2:表示属性节点

​ 3:表示文本节点

nodeType属性返回选定节点的节点类型,可以让我们知道、区分文档中的各个节点。

1
2
3
4
5
6
7
8
9
10
11
function test9(){
//元素节点的nodeType
alert(document.querySelector("#ul_1").nodeType);

//属性节点的nodeType
var node= document.getElementById("ul_1").attributes["class"];
alert(node.nodeType);

//文本节点的nodeType
alert(document.querySelector("#li_3").firstChild.nodeType);
}

二、操作DOM节点

2.1 创建一个节点

createElement、createTextNode

createElement() 方法通过指定名称创建一个元素

使用createElement创建节点:

例:创建一个p标签追加到body

1
2
3
4
5
6
7
8
9
10
11
12
13
<h2>createElement() 方法</h2>
<p>创建带一些文本的 p 元素:</p>
<script>
window.onload=function(){
// 用createElement创建元素
var c= document.createElement("p");
//设置元素的文本
c.innerText = "这是一个p标签";

// 追加到 body
document.body.appendChild(c);
}
</script>

注:1.createElement()创建了一个新的元素,参数是String类型的创建元素的名称

​ 2.createElement()方法常和appendChild()一起用。createElement()方法创建元素后,一般用appendChild()加入内容。

createTextNode() 方法创建文本节点

使用createTextNode创建节点:

例:创建一个节点追加到body里面

效果图:

1
2
3
4
5
6
7
8
<script>
window.onload=function(){
//使用createTextNode创建文本节点
var textNode = document.createTextNode("Hello World");
//追加到body
document.body.appendChild(textNode);
}
</script>

2.2 向页面加入一个节点

appendChild、insertBefore

例:创建一个li元素在里面创建一个文本节点再添加到已有的子元素前面

效果图:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
<ul id="myList">
<li id="a">hello</li><li id="b">world</li>
</ul>
<script>
window.onload=function(){
// 创建 "li" 元素:
var newNode = document.createElement("li");
// 创建文本节点:
var textNode = document.createTextNode("JQuery");
// 向 "li" 元素添加文本节点:
newNode.appendChild(textNode);

// 在已有子元素之前插入
var list = document.getElementById("myList");
list.insertBefore(newNode, list.children[0]);
}
</script>

案例中的appendChild() 方法,将新元素作为父元素的最后一个子元素进行添加。如果需要将新元素添加到开始位置,可以使用 insertBefore() 方法。

注:1. insertBefore() 方法是在被选元素前插入 HTML 元素。

​ 2.如需在被选元素后插入 HTML 元素,使可用 insertAfter() 方法。

​ 3.如果参数是已存在的元素,它将从它的当前位置被移除,并被插入在被选元素之前。

2.3 删除页面中的某一个节点

removeChild():删除 参数是要删除的对象。返回值是removeChild前的那个父节点

例:点击按钮删除第一个子节点

删除前:

删除后:

1
2
3
4
5
6
7
8
9
10
11
12
13
<button onclick="myFunction()">删除第一个子节点</button>
<ul id="myList">
<li id="a">hello</li><li id="b">world</li>
</ul>

<script>
function myFunction() {
//获取id
var list = document.getElementById("myList");
//通过id删除第一个节点
list.removeChild(list.firstElementChild);
}
</script>

注:1.如需删除 HTML 元素,您必须清楚该元素的父元素。DOM 需要了解您需要删除的元素,以及它的父元素, 所以无法在不引用父元素的情况下删除某个元素。

​ 2.如果不清楚父元素,可以先找到您需要删除的子元素,然后使用parentNode属性来查找其父元素

2.4 修改页面中的某一个节点

replaceChild() 方法: 替换 HTML DOM 中的元素。

例:点击替换获取第一个子元素创建新的文本节点并替换掉第一个子元素的文本

替换前:

替换后:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
<ul id="myList">
<li id="a">hello</li><li id="b">world</li>
</ul>
<button onclick="myFunction()">替换</button>

<script>
function myFunction() {
// 选取第一个子元素:
var element = document.getElementById("myList").children[0];

// 创建新的文本节点:
var newNode = document.createTextNode("JavaScript");

// 替换文本节点:
element.replaceChild(newNode, element.childNodes[0]);
}
</script>

注:1.replaceChild() 方法可将某个子节点替换为另一个。新节点可以是文本中已存在的,或者是你新创建的。

​ 2.新节点是要插入的节点对象,括号内第一个。之前的节点是要移除的节点对象,括号内的后一个。

​ 3.返回值为替换的新节点。

2.5 复制节点中的某一个节点:

cloneNode() 方法可创建指定的节点的精确拷贝。

cloneNode() 方法 拷贝所有属性和值。

该方法将复制并返回调用它的节点的副本。

cloneNode(true)参数deep是boolean型。true/false

​ true:表示深度复制(将节点及其子节点都进行复制)—- 深拷贝

​ false:表示浅复制(只复制节点而不复制子节点)—- 浅拷贝

例:点击按钮复制最后一个节点追加到对应列表id后面

复制前:

复制后:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
<button onclick="myFunction()">复制</button>
<ul id="myList1"><li>JS</li><li id="b">JQ</li></ul>
<ul id="myList2"><li>HTML</li><li>Css</li></ul>

<script>
function myFunction() {
//获取列表id的最后一个节点
var node = document.getElementById("myList2").lastChild;
//将节点复制
var clone = node.cloneNode(true);
//将节点追加到对应的列表id后面
document.getElementById("myList1").appendChild(clone);
}
</script>

2.6 获取元素的非行间样式:

getComputedStyle(非IE使用)、currentStyle(IE使用)

例:获取背景颜色的属性值赋值到对应的文本

效果图:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
<h2 id="test" style="background-color:pink">getComputedStyle() 方法</h2>
<p id="demo"></p>
<script>
window.onload=function(){
//获取id
var get = document.getElementById("test");
//获取id的样式
var cssObj = window.getComputedStyle(get, null);
//通过样式找到对应背景颜色的属性值
var bgColor = cssObj.getPropertyValue("background-color");
//将属性值赋给对应的文本id
document.getElementById("demo").innerHTML = bgColor;
}
</script>

三、课后作业

  • 预习

  • 完成课堂上机练习

    • 练习1:单击“删除”按钮,使用parentNode访问当前节点的父亲节点等,使用removeChild( )删除当前商品

      效果如下;

      素材:

      shoppingBg

    • 练习2: 完成动态生成表格案例,具体要求如下。

      1. 使用数组把学生数据模拟出来。

      2. 动态创建行、单元格。

      3. 为单元格填充数据。

      4. 提供“删除”链接,可删除所在的行。

      案例的实现效果如下图所示。