DOM 节点以树形结构组织,根节点为文档节点,文档节点下面包含了元素节点、属性节点、文本节点等子节点。
页面中所有的内容:标签、属性、文本(文字、换行、空格、回车)都属于节点。
// 获取标签的父节点
/*
<div id="dv4">
<p id="p1"></p>
<span></span>
<ul id="uu">
<li>第一个</li>
<li>第二个</li>
</ul>
</div>
*/
var obj = document.getElementById("p1").parentNode;
// 输出 <div id="dv4">
console.log(obj);
// 依次输出:1、DIV、null
console.log("节点的类型:" + obj.nodeType + ",节点的名字:" + obj.nodeName + ",节点的值:" + obj.nodeValue);
// 获取标签父节点的父节点
var obj = document.getElementById("p1").parentNode.parentNode;
// 获取父级元素
console.log(document.getElementById("dv4").parentElement);
// 获取子节点(返回的是数组)
var obj1 = document.getElementById("dv4").childNodes;
// 输出:NodeList(7) [ #text, p#p1, #text, span, #text, ul, #text ],因为文字、换行、空格、回车都属于节点,所以一共有7个节点
console.log(obj1);
// 获取第一个子节点(在 IE8 及以下中可能不支持)
console.log(document.getElementById("dv4").firstChild);
// 获取最后一个子节点(在 IE8 及以下中可能不支持)
console.log(document.getElementById("dv4").lastChild);
// 获取子元素
var obj2 = document.getElementById("dv4").children;
// HTMLCollection { 0: p#p1, 1: span, 2: ul, length: 3, … },所以一共有 3 个子元素
console.log(obj2);
// 获取第一个子元素(在 IE8 及以下中可能不支持)
console.log(document.getElementById("dv4").firstElementChild);
// 获取最后一个子元素(在 IE8 及以下中可能不支持)
console.log(document.getElementById("dv4").lastElementChild);
// 元素的前一个兄弟节点
document.getElementById("p1").previousSibling;
// 元素的前一个兄弟元素
document.getElementById("p1").previousElementSibling;
// 元素的后一个兄弟节点
document.getElementById("p1").nextSibling;
// 元素的后一个兄弟元素
document.getElementById("p1").nextElementSibling;
// 点击按钮,设置 div 里的 p 标签变背景色
document.getElementById("btn").onclick = function(){
// 先获取 div
var divObj = document.getElementById("div1");
// 获取里面所有子节点
var nodes = divObj.childNodes;
// 遍历所有子节点
for(var i=0; i<nodes.length; i++){
// 判断这个子节点是不是 p 标签
if(nodes[i].nodeType == 1 && nodes[i].nodeName == "P"){
nodes[i].style.backgroundColor = "red";
}
}
}
// 点击按钮,让 li 隔行变色
document.getElementById("btn").onclick = function(){
// 因为ul中文本、换行也算是节点,所以这里需要记录下真正的 li 节点有多少个
var count = 0;
// 获取 ul 中所有子节点
var nodes = document.getElementById("uu").childNodes;
for(var i=0; i<nodes.length; i++){
// 判断这个节点是不是 li 标签
if(nodes[i].nodeType == 1 && nodes[i].nodeName == "li"){
nodes[i].style.backgroundColor = count%2 == 0 ? "red":"yellow";
count++;
}
}
}
// 克隆一个元素
var obj = document.getElementById("uu").children[0].cloneNode(true);
/* 之所以封装,是为了解决不同浏览器支持的代码不一样的问题,问题如下:
element.firstChild ---> 谷歌和火狐获取的是第一个子节点
element.firstChild ---> IE8 获取的是第一个子元素
element.firstElementChild ---> 谷歌和火狐是第一个子元素,但 IE8 不支持
element.lastChild ---> 谷歌和火狐获取的是第一个子节点
element.lastChild ---> IE8 获取的是第一个子元素
element.lastElementChild ---> 谷歌和火狐是第一个子元素,但 IE8 不支持 */
// 获取任意一个父级元素的第一个子元素
function getFirstElementChild(element){
// 如果浏览器支持,会返回第一个子元素,if 判断的结果就是 true
// 如果浏览器不支持,会返回 undefined,if 判断的结果就是 false
if(element.firstElementChild){
return element.firstElementChild;
}else{
var node = element.firstChild;
// 如果 node 是空节点,或者不是标签节点,就继续取下一个节点
while(node && node.nodeType != 1){
node = node.nextSibling;
}
return node;
}
}
// 获取任意一个父级元素的最后一个子级元素
function getLastElementChild(element){
// 如果浏览器支持,会返回最后一个子元素,if 判断的结果就是 true
// 如果浏览器不支持,会返回 undefined,if 判断的结果就是 false
if(element.lastElementChild){
return element.lastElementChild;
}else{
// 如果 node 是空节点,或者不是标签节点,就继续取前一个节点
var node = element.lastChild;
while(node && node.nodeType != 1){
node = node.previousSibling;
}
return node;
}
}