本文详细总结了JavaScript中获取DOM子节点、父节点及兄弟节点的多种方法。涵盖firstChild、parentNode等基础属性,以及基于nodeType筛选元素节点的封装技巧。同时解析了jQuery源码中的兄弟节点处理逻辑,提供实用代码示例,帮助开发者高效操作DOM结构。
JavaScript DOM节点操作:子、父、兄弟节点获取详解
在实际的前端开发场景中,开发者经常需要定位并操作页面上的HTML元素,以动态修改其样式、内容或属性。
JavaScript原生提供了多种获取DOM节点的方法,主要包括获取子节点、父节点以及兄弟节点的途径。
常规获取方式
常规获取方式
通过父节点获取子节点
可以使用parentObj.firstChild获取已知父节点的第一个直接子节点;使用parentObj.lastChild获取最后一个直接子节点;通过parentObj.childNodes获取包含所有直接子节点的数组(在IE 7中仅包含直接子节点);利用parentObj.children获取直接子节点数组(在IE 7中与childNodes行为一致);此外,parentObj.getElementsByTagName(tagName)可返回指定标签名的子节点数组。
通过相邻节点获取兄弟节点
利用neighbourNode.previousSibing可以获取已知节点的前一个兄弟节点;通过neighbourNode.nextSibing获取下一个兄弟节点。
通过子节点获取父节点
使用childNode.parentNode属性即可获取已知节点的直接父节点。
上述常规方法支持链式递归调用,例如parentObj.firstChild.firstChild...,但这种写法代码冗长且可读性较差。
扩展方法
扩展方法
在深入扩展之前,需了解DOM节点的基本类型知识:每个DOM节点都对应特定的类型标识。
根据W3C规范,常用的DOM节点类型包括以下几种。
| 节点类型 | 说明 | 值 |
| 元素节点 | 每一个HTML标签都是一个元素节点 | 1 |
| 属性节点 | 元素节点(HTML标签)的属性,如id,class,name等 | 2 |
| 文本节点 | 元素节点或属性节点中的文本内容 | 3 |
| 注释节点 | 便是文档的注释,形式如<!--comment Text--> | 8 |
| 文档节点 | 表示整个文档(Dom树的根节点,即document) | 9 |
不同类型的节点具有不同的名称标识。
| 节点类型 | 节点名称 |
| 元素节点 | HTML的名称(大写) |
| 属性节点 | 属性的名称 |
| 文本节点 | 它的值永远的都#text |
| 文档节点 | 它的值永远都是#document |
可以通过nodeType属性返回节点类型,nodeName返回节点名称,nodeValue返回节点值(例如元素节点的nodeType为1,属性节点为2)。
JS获取兄弟节点的两种实现方式
JS获取兄弟节点的两种实现方式
方法一:通过父元素的子元素集合找到包含自身在内的所有兄弟元素,然后剔除自身。
function sibling(elem){
var a = [];
var b = elem.parentNode.children;
for (var i = 0 ; i < b.length ; i++){
if(b[i] !== elem) a.push(b[i]);
}
return a;
}
方法二:参考jQuery的实现逻辑,先定位元素的第一个子节点,然后遍历后续节点,判断并排除自身。
siblings:function(elem)
{
return JQuery.sibling(elem.parentNode.firstNode,elem);
}
JQuery.sibling = function(n,elem){
var r = [];
for (;n;n= n.nextSibling){
if(n.nodeType == 1 && (!elem || elem != elem))
r.push(n);
}
return r;
}
在jQuery 1.2.x版本(如1.2.3)中,该逻辑位于源码约1800行处。
将上述逻辑转化为独立可用的函数如下。
fucntion sibling(elem){
var r = [];
var n = elem.parentNode.firstChild;
for(;n;n = n.nextSibling) {
if(n.nodeType === 1 && n !== elem) {
r.push(n);
}
}
return r;
}
显然,通过这种方式查找特定节点的兄弟元素,能有效避免递归调用带来的代码冗余。
获取所有元素子节点
获取所有元素子节点
在JavaScript中,可以使用children属性获取所有子节点(仅返回HTML元素,甚至可能不返回子节点),该方法在大多数浏览器中兼容,但在部分Firefox版本中可能不支持。
注意:在IE浏览器中,children属性包含注释节点。
因此,若需仅获取元素节点,可利用nodeType属性进行筛选,其中nodeType等于1的节点即为元素节点。
基于上述知识,可以自定义一个函数来筛选并获取所有元素子节点。
var getChildNodes = function(elem) {
var childArr = elem.children || elem.childNodes,
childArrTem = new Array();
for (var i = 0 ; i < childArr.length; i ++ ) {
if (childArr[i].nodeType == 1){
childArrTem.push(childArr[i]);
}
}
return childArrTem;
}
获取所有父节点
获取所有父节点
同理,我们可以编写代码来获取当前节点的所有祖先节点。
function getParents (elem){
var parents = [];
while(elem.parentNode){
parents.push(elem.parentNode)
elem = elem.parentNode;
}
return parents;
}
该函数接收一个DOM节点作为输入,最终可遍历至document对象。若希望仅获取到body层级为止,可将while循环的判断条件修改为: while(elem.parentNode && elem.parentNode.tagName == 'BODY'
基于JavaScript提供的节点获取方法及相关知识,可以封装出多种实用的节点操作函数。读者可以尝试编写更多获取节点的封装方法。
当掌握了节点操作的封装技巧后,再阅读jQuery中DOM操作相关的源码将会更加轻松。
总结
以上介绍了JavaScript中获取子节点、父节点和兄弟节点的常用方法及封装技巧,希望对读者有所帮助。如有疑问欢迎留言,小编会及时回复。感谢对本站的支持!