元素节点的 parentNode 属性将返回它的父节点。父节点一定是 nodeType 等于 1 的元素节点。
例如制作一个小特效:页面上罗列一些复选框,当用户勾选某个复选框的时候,它的父元素将改变背景颜色;
当用户去掉勾选复选框的时候,它的父元素的背景颜色恢复。
代码如下:
<!DOCTYPE html>
<head>
<meta charset=UTF-8>
<title>父节点</title>
</head>
<body>
<div>
<p>
<input type="checkbox" /> 足球
</p>
<p>
<input type="checkbox" /> 篮球
</p>
<p>
<input type="checkbox" /> 排球
</p>
<p>
<input type="checkbox" /> 羽毛球
</p>
</div>
<script type="text/javascript">
//得到所有复选框
var oCheckBoxs = document.getElementsByTagName("input");
//循环添加监听
for(var i = 0 ; i < oCheckBoxs.length ; i++){
oCheckBoxs[i].onclick = function(){
//当点击某一个 input 的时候,如果自己被选中了,改变父亲的颜色;否则恢复颜色。
if(this.checked){
this.parentNode.style.background = "gold";
}else{
this.parentNode.style.background = "white";
}
}
}
</script>
</body>
</html>
程序中使用循环语句给所有的复选框都添加了事件监听,当点击复选框的时
候,判断此时该复选框的 checked 属性。根据 checked 属性是 true 或 false,分别给它的父节点设置不同的
背景颜色。
兄弟节点
兄弟节点概述
DOM 提供了访问某节点的兄弟节点的两个属性 nextSibling、previousSibling,分别表示节点的前一个兄弟和后一个兄弟。文本节点(含空文本节点)也会被算作是 nextSibling 或 previousSibling。
我们写程序来验证:
<!DOCTYPE html>
<head>
<meta charset=UTF-8>
<title>Document</title>
</head>
<body>
<div>
<p></p>
<p></p>
<p id="para"></p>
<p></p>
</div>
<script type="text/javascript">
//得到 para
var oPara = document.getElementById("para");
//得到 para 的前一个兄弟
var pSbling = oPara.previousSibling;
//输出 para 的前一个兄弟的节点类型
console.log(pSbling.nodeType); //3
</script>
</body>
</html>
控制台输出 3,即标签 p#para 的前一个兄弟节点并不是它前一个 p 标签节点 ,而是它前面的空文本节点。
过滤元素兄弟节点
我们编写函数来得到 elem 元素的真正的前一个元素兄弟节点:
//得到前面一个标签节点
function getRealPrev(elem){
var o = elem;
//开始遍历 elem 节点前面的节点 ,直到遇见一个 nodeType 为 1 的节点
//循环遍历。注意 while 的条件是一个赋值语句,赋值语句也有表达式的值,就是等号右边的值
while(o = o.previousSibling){
if(o.nodeType == 1){
return o;
}
}
return null;
}
程序中循环语句不断的遍历元素 o 的前面一个兄弟、前面一个兄弟的前面一个兄弟…,看看它们的 nodeType
是不是 1,如果是,则返回这个节点,随着函数的返回,循环语句也就结束了。
同样的道理,我们可以写出得到后面一个元素兄弟的函数:
//得到后面一个标签节点
function getRealNext(elem){
var o = elem;
//开始遍历 elem 节点后面的节点,直到遇见一个 nodeType 为 1 的节点
//循环遍历。注意 while 的条件是一个赋值语句!赋值语句也有表达式的值,就是等号右边的值!
while(o = o.nextSibling){
if(o.nodeType == 1){
return o;
}
}
return null;
}
在实际应用中,我们很可能需要得到某一个元素前面所有兄弟节点(而不是就得到前面一个)。程序如下:
//得到前面所有标签节点
function getRealPrevAll(elem){
var o = elem;
var result = [];
//循环遍历,将所有 nodeType 是 1 的节点都放入数组中
while(o = o.previousSibling){
if(o.nodeType == 1){
result.unshift(o);
}
}
return result;
}
我们可以测试这个函数,例如 HTML 结构是:
<div>
<p></p>
<p></p>
<p id="para"></p>
<p></p>
</div>
测试语句:
console.log(getRealPrevAll(oPara).length); //2
控制台中输出 2,表示这是#para 前面有 2 个标签兄弟节点。