JS获取子、父、兄节点方法小结


Posted in Javascript onAugust 14, 2017

我们在实际的开发中,经常要获取页面中某个html元素,动态更新元素的样式、内容属性等。

 我们已经知道在JavaScript中提供下面的方法获取子、父、兄节点的方法:

  常规

通过父节点获取子节点:

parentObj.firstChild

                                          获取已知父节点的第一个子节点
parentObj.lastChild

                                          获取已知父节点的最后一个子节点
parentObj.childNodes                                             获取已知父节点的子节点数组(这里我在IE 7中获取的是所有直接的子节点)
parentObj.children                                                  获取已知节点的直接子节点数组(在IE7中和childNodes效果一样)
parentObj.getElementsByTagName(tagName)     返回已知子节点中类型为指定值的子节点数组

通过临近节点获取兄弟节点:

neighbourNode.previousSibing                              获取已知节点的前一个兄弟节点
neighbourNode.nextSibing                                      获取已知节点的下一个兄弟节点

通过子节点获取父节点:

1、childNode.parentNode                                             获取已知节点的父节点

上面的方法基本都是可以递归是使用的,parentObj.firstChild.firstChild.firstChild...但是这样的代码有一种傻傻的赶脚。。

扩展

在扩展之前,我们需要知道一些关于节点基础的知识:Dom节点中,每个节点都拥有不同的类型

     W3C规范中常用的Dom节点的类型有以下几种

节点类型 说明
元素节点 每一个HTML标签都是一个元素节点 1
属性节点 元素节点(HTML标签)的属性,如id,class,name等 2
文本节点 元素节点或属性节点中的文本内容 3
注释节点 便是文档的注释,形式如 8
文档节点 表示整个文档(Dom树的根节点,即document) 9

   关于节点的名称,不同类型的节点对应不同的名称

节点类型 节点名称
元素节点 HTML的名称(大写)
属性节点 属性的名称
文本节点 它的值永远的都#text
文档节点 它的值永远都是#document

   可以分别通过nodeType(节点类型),nodeName(节点名称),以及nodeValue(节点值)分别返回节点的类型、节点名称以及节点值(比如元素节点返回1,属性节点返回2)

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多的版本中都可以找到这段代码,我看的jQuery1.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操作节点方法的源码会轻松很多呢。

总结

以上所述是小编给大家介绍的JS获取子、父、兄节点方法小结,希望对大家有所帮助,如果大家有任何疑问请给我留言,小编会及时回复大家的。在此也非常感谢大家对三水点靠木网站的支持!

Javascript 相关文章推荐
服务器安全设置的几个注册表设置
Jul 28 Javascript
JQuery优缺点分析说明
Jun 09 Javascript
jQuery事件之键盘事件(ctrl+Enter回车键提交表单等)
May 11 Javascript
js的window.showModalDialog及window.open用法实例分析
Jan 29 Javascript
原生js和jQuery实现淡入淡出轮播效果
Dec 25 Javascript
JQuery用户名校验的具体实现
Mar 18 Javascript
点击页面任何位置隐藏div的实现方法
Sep 05 Javascript
AngularJS通过ng-route实现基本的路由功能实例详解
Dec 13 Javascript
快速将Vue项目升级到webpack3的方法步骤
Sep 14 Javascript
详解如何使用webpack在vue项目中写jsx语法
Nov 08 Javascript
微信小程序封装分享与分销功能过程解析
Aug 13 Javascript
详解Vue2的diff算法
Jan 06 Vue.js
JS传播事件、取消事件默认行为、阻止事件传播详解
Aug 14 #Javascript
JS如何实现在页面上快速定位(锚点跳转问题)
Aug 14 #Javascript
JavaScript实现动态添加Form表单元素的方法示例
Aug 14 #Javascript
JavaScript实现的搜索及高亮显示功能示例
Aug 14 #Javascript
带你了解session和cookie作用原理区别和用法
Aug 14 #Javascript
react.js使用webpack搭配环境的入门教程
Aug 14 #Javascript
JS原生数据双向绑定实现代码
Aug 14 #Javascript
You might like
PHP中file_exists()判断中文文件名无效的解决方法
2014/11/12 PHP
PHP中字符安全过滤函数使用小结
2015/02/25 PHP
PHP进程通信基础之信号
2017/02/19 PHP
thinkphp 字母函数详解T/I/N/D/M/A/R/U
2017/04/03 PHP
Javascript实例教程(19) 使用HoTMetal(2)
2006/12/23 Javascript
Javascript编程之继承实例汇总
2015/11/28 Javascript
详细解读Jquery各Ajax函数($.get(),$.post(),$.ajax(),$.getJSON())
2016/08/15 Javascript
vue.js表格分页示例
2016/10/18 Javascript
ReactJS实现表单的单选多选和反选的示例
2017/10/13 Javascript
Vue官方推荐AJAX组件axios.js使用方法详解与API
2018/10/09 Javascript
JS module的导出和导入的实现代码
2019/02/25 Javascript
javascript 高级语法之继承的基本使用方法示例
2019/11/11 Javascript
微信小程序点击生成朋友圈分享图(遇到的坑)
2020/06/17 Javascript
vue 全局封装loading加载教程(全局监听)
2020/11/05 Javascript
python多重继承实例
2014/10/11 Python
用Python实现一个简单的多线程TCP服务器的教程
2015/05/05 Python
Python基于动态规划算法计算单词距离
2015/07/25 Python
python开发利器之ulipad的使用实践
2017/03/16 Python
python自动截取需要区域,进行图像识别的方法
2018/05/17 Python
python print输出延时,让其立刻输出的方法
2019/01/07 Python
pyinstaller打包单个exe后无法执行错误的解决方法
2019/06/21 Python
django ListView的使用 ListView中获取url中的参数值方式
2020/03/27 Python
关于css兼容性问题及一些常见问题汇总
2016/05/03 HTML / CSS
美国鲜花递送:UrbanStems
2021/01/04 全球购物
《商鞅南门立木》教学反思
2014/02/16 职场文书
企业口号大全
2014/06/12 职场文书
医院领导班子查摆问题对照检查材料思想汇报
2014/10/08 职场文书
三提三创主题教育活动查摆整改措施
2014/10/25 职场文书
档案工作个人总结
2015/03/03 职场文书
毕业赠语大全
2015/06/23 职场文书
2015年暑假工作总结
2015/07/13 职场文书
幼儿园开学家长寄语(2016秋季)
2015/12/03 职场文书
市语委办2016年第十九届“推普周”活动总结
2016/04/05 职场文书
导游词之日月潭
2019/11/05 职场文书
MySQL 覆盖索引的优点
2021/05/19 MySQL
html+css实现滚动到元素位置显示加载动画效果
2021/08/02 HTML / CSS