DOM
恶魔“产品经理”的手终于伸向我这小可爱了^~^
一、DOM基础
DOM是文档对象模型(document object model),将文档抽象成一个树型结构,文档中的标签、标签属性或标签内容可以表示为树上的结点,称为DOM树。如:
文档中的所有内容都可表示为一个节点(node),如:HTML里整个文档、每个标签、每个标签的属性和文本都可作为一个节点。
① 文档节点(Document):整个XML、HTML文档
② 元素节点(Element):每个XML、HTML元素
③ 属性节点(Attr):每个XML、HTML元素的属性
④ 文本节点(Text):每个XML、HTML元素内的文本
⑤ 注释节点(Comment):每个注释
节点层次关系:
父(parent)、子(child)和同胞(sibling)等术语用于描述这些关系。父节点拥有子节点。同级的子节点被称为同胞(兄弟或姐妹)。
- 在节点树中,顶端节点被称为根(root)
- 每个节点都有父节点、除了根(它没有父节点)
- 一个节点可拥有任意数量的子节点
- 同胞是拥有相同父节点的节点
二、DOM操作
2.1获取DOM节点
通过使用 getElementById() 方法匹配元素的id属性来访问元素节点,对元素节点进行操作
通过使用 getElementsByTagName() 方法匹配元素的tagName来访问元素节点,对元素节点进行操作
通过使用 getElementsByClassName() 方法匹配元素的className来访问元素节点,对元素节点进行操作
值得注意的是, getElementsByTagName() 和 getElementsByClassName() 这两种方法得到的会是一个以数组的形式来体现出来的元素节点集合。而getElementById()方法得到的却是一个节点。
<!doctype html> <html> <head> </head> <body> <div class="warpper"> <div class="header"> <div class="logo">蒋涂涂1</div> <div class="logo">蒋涂涂2</div> <div class="logo">蒋涂涂3</div> <div class="nav"> <a href="index.html">首页</a> <a href="photo.html">影集</a> <a href="news.html">故事</a> <a href="#">作品</a> </div> </div> <div class="main"> <span id="hello">hello!</span> </div> <div class="footer"></div> </div> <script> console.log(document.getElementById("hello")); console.log(document.getElementsByTagName("div")); console.log(document.getElementsByClassName("logo")); </script> </body> </html>
结果为:
第二种方法是使用querySelector()
和querySelectorAll()。
// 通过querySelector获取ID为q1的节点: var q1 = document.querySelector('#q1'); // 通过querySelectorAll获取q1节点内的符合条件的所有节点: var ps = q1.querySelectorAll('div.highlighted > p');
2.2节点属性innerHTML、innerText、nodeName、nodeValue以及nodeType等。
innerHTML:获取元素内容的最简单方法是使用 innerHTML 属性。innerHTML 属性对于获取或替换 HTML 元素的内容很有用。
innerText以文本字符串的形式获取或设置节点的内容,注意只获取文本内容。
<html> <body> <div id="intro"> 蒋涂涂1 <span>蒋涂涂2</span> </div> <script> var txt = document.getElementById("intro"); console.log(txt.innerText); txt.innerText = "你好漂亮" console.log(txt.innerText); </script> </body> </html>
nodeName 属性规定节点的名称。
- nodeName 是只读的
- 元素节点的 nodeName 与标签名相同
- 属性节点的 nodeName 与属性名相同
- 文本节点的 nodeName 始终是 #text
- 文档节点的 nodeName 始终是 #document
注释:nodeName 始终包含 HTML 元素的大写字母标签名。
nodeValue 属性规定节点的值。
- 元素节点的 nodeValue 是 undefined 或 null
- 文本节点的 nodeValue 是文本本身
- 属性节点的 nodeValue 是属性值
nodeType 属性返回节点的类型。nodeType 是只读的。
2.3DOM节点方法
创建新的节点:appendChild()
如需向 HTML DOM 添加新元素,首先必须创建该元素,然后把它追加到已有的元素上。
<html> <body> <div id="div1"> <p id="p1">This is a paragraph.</p> <p id="p2">This is another paragraph.</p> </div> <script> var para = document.createElement("p"); //创建了一个新的 <p> 元素: var node = document.createTextNode("This is new."); //创建文本节点 para.appendChild(node); //向 <p> 元素追加文本节点 var element = document.getElementById("div1"); //查找到一个已有的元素 element.appendChild(para); //向这个已存在的元素追加新元素 </script> </body> </html>
页面会打印三句话:
This is a paragraph.
This is another paragraph.
This is new.
创建新的节点:insertBefore()
<html> <body> <div id="div1"> <p id="p1">This is a paragraph.</p> <p id="p2">This is another paragraph.</p> </div> <script> var para = document.createElement("p"); var node = document.createTextNode("This is new."); para.appendChild(node); var element = document.getElementById("div1"); var child = document.getElementById("p1"); element.insertBefore(para, child); </script> </body> </html>
页面输出:
This is new.
This is a paragraph.
This is another paragraph.
删除 HTML 元素:removeChild()这种方法必须在知道该节点的父节点额度情况下使用。
<html> <body> <div id="div1"> <p id="p1">This is a paragraph.</p> <p id="p2">This is another paragraph.</p> </div> <script> var parent = document.getElementById("div1"); //查找 id="div1" 的元素: var child = document.getElementById("p1"); //查找 id="p1" 的 <p> 元素: parent.removeChild(child); //从父元素中删除子元素: </script> </body> </html>
页面效果:
This is another paragraph.
替换HTML元素:replaceChild()
<html> <body> <div id="div1"> <p id="p1">This is a paragraph.</p> <p id="p2">This is another paragraph.</p> </div> <script> var para = document.createElement("p"); var node = document.createTextNode("This is new."); para.appendChild(node); var parent = document.getElementById("div1"); var child = document.getElementById("p1"); parent.replaceChild(para, child); </script> </body> </html>
页面效果为:
This is new.
This is another paragraph.
添加节点:
1、添加文本节点:var text = document.createTextNode("文本内容");
2、添加元素节点:var ele = document.createElement("元素名");
3、对某个节点创建属性:document.createAttribute(attrName);
复制节点:
cloneNode(true | false); //复制某个节点 参数:是否复制原节点的所有属性
例如:
var deepList = someNode.cloneNode(true);参数为true为深复制,连子节点一起复制。
var shallowList = someNode.cloneNode(false);参数为false为浅复制,不复制子节点。
<!doctype html> <html> <head> </head> <body> <div class="warpper"> <div class="main"> <div id="hello"> hello! <span>good moring!</span> </div> </div> <script> var node1 = document.getElementById("hello"); var node2 = node1.cloneNode(true); var node3 = node1.cloneNode(false); console.log(node1); console.log(node2); console.log(node3); </script> </body> </html>
第一个是原节点,第二个是对节点进行深复制,将子节点一并复制。第三个是对节点进行浅复制,只复制了当前节点,对子节点没有进行复制。
查找结点:
1. .childNodes: 获取当前节点的所有子节点(包括元素节点和文本节点)。
.children: 获取当前节点的所有元素子节点(不包含文本节点)。
<!doctype html> <html> <head> </head> <body> <div class="warpper"> <div class="main"> <div id="hello"> <span>dog1</span> <span>dog2</span> <span>dog3</span> <span>dog4</span> <span>dog5</span> </div> </div> <script> var node1 = document.getElementById("hello"); var node2 = node1.childNodes; var node3 = node1.children; console.log(node1); console.log(node2); console.log(node3); </script> </body> </html>
2. .parentNode: 获取当前节点的父节点。
<div class="warpper"> <div class="main"> <div id="hello"> <span>dog1</span> <span>dog2</span> <span>dog3</span> <span>dog4</span> <span>dog5</span> </div> </div> <script> var node1 = document.getElementById("hello"); var node2 = node1.parentNode; console.log(node1); console.log(node2); </script>
3. .firstChild: 获取第一个子节点,包括回车等文本节点;
.firstElementChild: 获取第一个元素节点。 不含文本节点;
.lastChild: 获取最后一个子节点,包括回车等文本节点;
.lastElementChild: 获取最后一个子节点,不含文本节点;
<div class="warpper"> <div class="main"> <div id="hello"> <span>dog1</span> <span>dog2</span> <span>dog3</span> <span>dog4</span> <span>dog5</span> </div> </div> <script> var node1 = document.getElementById("hello"); var node2 = node1.firstChild; var node3 = node1.firstElementChild; var node4 = node1.lastChild; var node5 = node1.lastElementChild; console.log(node1); console.log(node2); console.log(node3); console.log(node4); console.log(node5); </script>
4. .previousSibling: 获取当前节点的前一个兄弟节点,包括文本节点;
.previousElementSibling: 获取当前节点的前一个元素兄弟节点;
.nextSibling:获取当前节点的后一个兄弟节点,包括文本节点;
.nextElementSibling:获取当前节点的后一个元素兄弟节点;
<div class="warpper"> <div class="main"> <div> <span>dog1</span> </div> <div id="hello"> hello 1 <span>dog2</span> </div> <div> hello 2 <span>dog3</span> </div> <div> hello 3 <span>dog4</span> </div> </div> <script> var node1 = document.getElementById("hello"); var node2 = node1.previousSibling; var node3 = node1.previousElementSibling; var node4 = node1.nextSibling; var node5 = node1.nextElementSibling; console.log(node1); console.log(node2); console.log(node3); console.log(node4); console.log(node5); </script>
5. .attributes: 获取当前节点的所有属性节点。 返回数组格式。
<div class="warpper"> <div class="main"> <div id="hello"style="font-size:20px;color:red"> hello 1 <span>dog2</span> </div> </div> <script> var node1 = document.getElementById("hello"); var node2 = node1.attributes; console.log(node1); </script>