JavaScript基础学习(九)—DOM
一、DOM概述
DOM(Document Object Model)文本对象模型。
D: 文档,HTML文档或XML文档。
O: 对象,document对象的属性和方法。
M: 模型。
(1)DOM是针对HTML/XML基于树的API。
(2)DOM树,节点(node)的层次。
(3)DOM把一个文档表示为一棵树。
1.节点及其类型
节点(node): 来源于网络,代表网络中的一个连接点。网络是由节点构成的集合。
(1)元素节点
(2)属性节点: 元素的属性,可以直接通过属性的方式来操作。
(3)文本节点: 是元素节点的子节点,其内容为文本。
2.Node接口的特性和方法
二、DOM的基本操作
1.获取元素节点
(1)getElementById(): 根据Id获取元素节点。
var element = document.getElementById(id);
该方法只能用于document。
(2)getElementsByTagName(): 根据标签名获取元素节点集合。
var element = element.getElementsByTagName(TagName);
该方法不必非得用在整个文档上。它也可以用来在某个特定元素的子节点当中寻找有着给定标签名的元素。
(3)getElementsByName(): 根据HTML标签的name属性获取指定元素节点集合。
var genderNodes = document.getElementsByName(name);
<body> <p>你喜欢哪个城市?</p> <ul id="city"> <li id="bj">北京</li> <li>上海</li> <li>东京</li> <li>首尔</li> </ul> <br><br> <p>你喜欢哪款单机游戏?</p> <ul id="game"> <li id="jh">饥荒</li> <li>穿越火线</li> <li>LOL</li> <li>WOW</li> </ul> <br><br> 性别: <input type="radio" name="gender" value="male"/>男 <input type="radio" name="gender" value="female"/>女 </body>
window.onload = function(){ /* * 1.根据Id获取元素节点 * 该方法为document的方法。 */ var bjNode = document.getElementById("bj"); alert(bjNode.value); /* * 2.根据HTML标签名获取元素节点集合 * 该方法为Node接口的方法,任何一个节点都有这个方法 */ var liNode = document.getElementsByTagName("li"); alert(liNode.length);//8 var cityNode = document.getElementById("city"); var liNodes = cityNode.getElementsByTagName("li"); alert(liNodes.length);//4 /* * 3.根据HTML元素的name属性名获取元素节点的集合 */ var genderNodes = document.getElementsByName("gender"); alert(genderNodes.length);//2 };
2.获取元素节点的子节点
(1)childNodes属性: 获取全部的子节点,但是该方法不实用,因为如果要获得指定节点的指定子节点的集合,可以直接调用元素节点的getElementByTagName()方法来获取。
(2)firstChild属性: 获取第一个子节点。
(3)firstChild属性: 获取最后一个字节点。
3.获取文本节点
步骤: (1)获取文本节点所在的元素节点。
(2)获取元素节点的第一个子节点。
(3)通过操作文本节点的nodeValue属性来读写文本节点的值。
<p>你喜欢哪个城市?</p> <ul id="city"> <li id="bj">北京</li> <li>上海</li> <li>东京</li> <li>首尔</li> </ul>
window.onload = function(){ //1.获取文本节点所在的元素节点 var bjNode = document.getElementById("bj"); //2.获取元素节点的第一个子节点 var bjTexttNode = bjNode.firstChild; //3.通过操作文本节点的nodeValue属性来读写文本节点的值 alert(bjTexttNode.nodeValue); };结果:
4.节点的属性
(1)nodeName
一个字符串,内容是给定节点的名字。
var name = node.nodeName;
注意: 如果是元素节点或属性节点,将返回这个元素的名字。
如果是文本节点,将返回"#text"的字符串。
nodeName是一个只读的属性。
(2)nodeType
返回一个整数,这个数值代表着给定节点的类型。
Node.ELEMENT_NODE (1) 元素节点
Node.ATTRIBUTE_NODE (2) 属性节点
Node.TEXT_NODE (3) 文本节点
注意: nodeType是个只读属性。
(3)nodeValue
返回给定节点的当前值。
注意: 如果是元素节点,返回值是null。
如果是属性节点,返回的是属性的值。
如果是文本节点,返回的是文本的内容。
nodeValue是一个读/写属性,不能对元素节点设置值,但可以为文本节点设置一个值。
<body> <p>你喜欢哪个城市?</p> <ul id="city"> <li id="bj">北京</li> <li>上海</li> <li>东京</li> <li>首尔</li> </ul> <br><br> <p>你喜欢哪款单机游戏?</p> <ul id="game"> <li id="jh">饥荒</li> <li>穿越火线</li> <li>LOL</li> <li>WOW</li> </ul> 密码: <input type="text" id="pwd" name="password"/> </body>
window.onload = function(){ //nodeType、nodeName是只读的,nodeValue是可改变的 //以上三个属性只有在文本节点中使用nodeValue使用的最多 //1.元素节点的3个属性 var bjNode = document.getElementById("bj"); alert(bjNode.nodeType); //元素节点: 1 alert(bjNode.nodeName); //节点名: li alert(bjNode.nodeValue); //元素节点没有nodeValue: null //2.属性节点 var nameAttr = document.getElementById("pwd").getAttributeNode("name"); alert(nameAttr.nodeType); //属性节点: 2 alert(nameAttr.nodeName); //节点名: 属性名,name alert(nameAttr.nodeValue); //属性值: password //3.文本节点 var bjTextNode = bjNode.firstChild; alert(bjTextNode.nodeType); //文本节点:3 alert(bjTextNode.nodeName); //节点名: #text alert(bjTextNode.nodeValue); //属性值: 北京 };
二、节点的增删改查
1.创建新元素节点
按照给定的标签名创建一个新的元素节点。方法只有一个参数: 将被创建的元素的名字,是一个字符串。
var reference = document.createElement();
方法的返回值: 是一个指向新建节点的引用指针,是一个元素节点。它的nodeType为1。
新的元素节点不会自动添加到文档里。
2.创建新的文本节点
创建一个包含着给定文本的新文本节点。
var reference = document.createTextNode(text);
方法的参数: 新建文本节点包含的文本字符串。
方法的返回值: 是一个指向新建节点的引用指针。它是一个文本节点,它的nodeTyoe为3。
新的元素节点不会自动添加到文档里。
3.插入节点
为给定元素增加一个子节点。
element.appendChild(newChild);
给定子节点将成为给定元素element的最后一个子节点。
方法的返回值: 是一个指向新增子节点的引用指针。
//新建一个元素节点,并把该节点添加到文档中指定节点的子节点 var liNode = document.createElement("li"); var textNode = document.createTextNode("厦门"); liNode.appendChild(textNode); var cityNode = document.getElementById("city"); cityNode.appendChild(liNode);结果:
4.替换节点
replaceChild()
把一个给定父元素里的一个子节点替换成另一个子节点。
aParentNode.replaceChild(newNode,aNode);
var cityNode = document.getElementById("city"); var bjNode = document.getElementById("bj"); var jhNode = document.getElementById("jh"); cityNode.replaceChild(jhNode, bjNode);
测试前: 测试后:
发现这只是单向的替换,所以我们为您编写一个通用的双向替换方法。
//节点的替换 var cityNode = document.getElementById("city"); var bjNode = document.getElementById("bj"); var jhNode = document.getElementById("jh"); exchange(bjNode, jhNode); //实现节点的互换 function exchange(aNode,bNode){ if(aNode == bNode){ return } var aParentNode = aNode.parentNode; var bParentNode = bNode.parentNode; if(aParentNode && bParentNode){ var tempNode = aNode.cloneNode(true); bParentNode.replaceChild(tempNode,bNode); aParentNode.replaceChild(bNode,aNode); } } };
测试结果:
5.删除节点
removeChild()
从一个给定元素删除一个子节点。
某个节点被删除时他的子节点将同时被删除。
//节点的删除 var cityNode = document.getElementById("city"); var bjNode = document.getElementById("bj"); cityNode.removeChild(bjNode);结果:
6.节点的插入
insertBefore()
把一个给定节点插入到一个给定元素节点的给定子节点的前面。
aParentNode.insertBefore(newNode,aNode);
//节点的插入 var cityNode = document.getElementById("city"); var bjNode = document.getElementById("bj"); var liNode = document.createElement("li"); var textNode = document.createTextNode("纽约"); liNode.appendChild(textNode); cityNode.insertBefore(liNode, bjNode);
结果:
由于没有插入到后面的方法,我们自己写一个。
三、练习
1.点击所有的li节点,显示它的值<body> <p>你喜欢哪个城市?</p> <ul id="city"> <li id="bj">北京</li> <li>上海</li> <li>东京</li> <li>首尔</li> </ul> <br><br> <p>你喜欢哪款单机游戏?</p> <ul id="game"> <li id="jh">饥荒</li> <li>穿越火线</li> <li>LOL</li> <li>WOW</li> </ul> </body>
//1.获取所有的li节点 var liNodes = document.getElementsByTagName("li"); //2.使用for循环遍历,得到每一个li节点 for(var i = 0; i < liNodes.length; i++){ //3.为每一个li节点添加onclick响应函数 liNodes[i].onclick = function(){ //4.获取当前节点的文本节点的文本值 //this为正在响应事件的那个节点 alert(this.firstChild.nodeValue); //alert(liNodes[i].firstChild.nodeValue);不显示 }; }; };