文章目录
⭐ 节点的关系
DOM中的各个节点的关系如下:
在实际工作中,页面上的一些文本节点可能会对我们的元素关系造成干扰,所以,从IE9
开始支持一些“只考虑元素节点”的属性:
示例代码:
<body>
<div id="box">
<p>我是段落</p>
<p id="para">我是段落</p>
<p>我是段落</p>
<p>我是段落</p>
</div>
<script>
var oBox = document.getElementById('box');
var para = document.getElementById('para');
//得到div#box下所有子节点
console.log(oBox.childNodes);
//得到div#box下所有元素子节点
console.log(oBox.children)
</script>
</body>
可以看到chidNodes
里面包含了文本节点(每个节点之间的换行就是文本节点),而children
里面只包含元素节点。
我们之前提到过,通过获取元素节点的方法得到的是一个对象,更具体点说,应该是一个类数组对象,里面不仅包含元素节点,还可以直接通过“打点调用”的方式访问具体的某个节点。
示例代码:
//得到拥有id属性para的节点
console.log(oBox.children.para)
再来看一些其他的节点关系的示例:
<body>
<div id="box">
<p>我是段落1</p>
<p id="para">我是段落2</p>
<p>我是段落3</p>
<p>我是段落4</p>
</div>
<script>
var oBox = document.getElementById('box');
var para = document.getElementById('para');
//父节点
console.log(para.parentNode);
//第一个子节点(考虑所有节点)
console.log(oBox.firstChild);
//第一个子节点(只考虑元素节点,IE9开始兼容)
console.log(oBox.firstElementChild);
//最后一个子节点(考虑所有节点)
console.log(oBox.lastChild);
//最后一个子节点(只考虑元素节点,IE9开始兼容)
console.log(oBox.lastElementChild);
//前一个兄弟节点(考虑所有节点)
console.log(para.previousSibling)
//后一个兄弟节点(只考虑元素节点,IE9开始兼容)
console.log(para.nextElementSibling);
</script>
</body>
再次强调: 使用“只包含元素节点”的属性时,一定要注意兼容性,如果产品对兼容性有很高的要求,就不能使用这种属性,而是需要通过书写一个节点关系函数
的方式来实现。下面就来介绍怎么书写这样的函数。
⭐ 书写常见的节点关系函数
首先,要回忆一个知识点——nodeType属性。nodeType属性等于1时,就代表这个节点是元素节点。
-
书写一个IE6也能兼容的“寻找所有元素子节点”的函数,类似
children
的功能示例代码:
<body> <div id="box"> <p>我是段落1</p> <p id="para">我是段落2</p> <p>我是段落3</p> <p>我是段落4</p> </div> <script> var box = document.getElementById('box'); var para = document.getElementById('para'); //封装一个函数,这个函数可以返回元素的所有子元素节点(兼容到IE6),类似children的功能 function getChildren(node) { //定义一个结果数组 var children = []; //遍历元素的子节点,判断nodeType是否等于1,等于1则推入结果数组 for (var i = 0; i < node.childNodes.length; i++){ if (node.childNodes[i].nodeType == 1) { children.push(node.childNodes[i]); } } return children; } var result = getChildren(box); console.log(result); </script> </body>
-
书写一个IE6也能兼容的“寻找前一个元素兄弟节点”的函数,类似previousElementSibling的功能
<body> <div id="box"> <p>我是段落1</p> <p id="para">我是段落2</p> <p>我是段落3</p> <p>我是段落4</p> </div> <script> var box = document.getElementById('box'); var para = document.getElementById('para'); //封装一个函数,这个函数可以返回某个元素的前一个元素兄弟节点(兼容到IE6),类似previousElementSibling的功能 function getElementPreviousSibling(node) { var o = node; //使用while语句 while (o.previousSibling != null) { if (o.previousSibling.nodeType == 1) { //结束循环,找到了 return o.previousSibling; } //让o成为它的前一个节点 o = o.previousSibling; } } var result = getElementPreviousSibling(para); console.log(result); </script> </body> </html>
- 书写一个IE6也能兼容的“寻找所有元素兄弟节点”的函数,类似对previousElementSibling和nextElementSibling的功能的整合
<body>
<div id="box">
<p>我是段落1</p>
<p id="para">我是段落2</p>
<p>我是段落3</p>
<p>我是段落4</p>
</div>
<script>
var box = document.getElementById('box');
var para = document.getElementById('para');
//封装一个函数,这个函数可以返回元素的所有元素兄弟节点(兼容到IE6),类似对previousElementSibling和nextElementSibling的功能的整合
function getAllElementSibling(node) {
//前面的元素兄弟节点
var prevs = [];
//后面的元素兄弟节点
var nexts = [];
var o = node;
while (o.previousSibling != null) {
if (o.previousSibling.nodeType == 1) {
prevs.unshift(o.previousSibling);
}
o = o.previousSibling;
}
o = node;
while (o.nextSibling != null) {
if (o.nextSibling.nodeType == 1) {
nexts.push(o.nextSibling);
}
o = o.nextSibling;
}
//将两个数字进行合并然后后返回
return prevs.concat(nexts);
}
var result = getAllElementSibling(para);
console.log(result);
</script>
</body>
</html>