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 相关文章推荐
一起来写段JS drag拖动代码
Dec 09 Javascript
远离JS灾难css灾难之 js私有函数和css选择器作为容器
Dec 11 Javascript
打印json对象的内容及JSON.stringify函数应用
Mar 29 Javascript
原生js实现shift/ctrl/alt按键的获取
Apr 08 Javascript
JavaScript中Array的实用操作技巧分享
Sep 11 Javascript
Bootstrap按钮组简单实现代码
Mar 06 Javascript
react开发中如何使用require.ensure加载es6风格的组件
May 09 Javascript
vue路由懒加载的实现方法
Mar 12 Javascript
JavaScript中常见内置函数用法示例
May 14 Javascript
详解如何探测小程序返回到webview页面
May 14 Javascript
node.js中npm包管理工具用法分析
Feb 14 Javascript
关于React Native使用axios进行网络请求的方法
Aug 02 Javascript
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 中文处理技巧
2010/04/25 PHP
使用PHP获取汉字的拼音(全部与首字母)
2013/06/27 PHP
ThinkPHP3.1新特性之字段合法性检测详解
2014/06/19 PHP
一个简单安全的PHP验证码类 附调用方法
2016/06/24 PHP
php getcwd与dirname(__FILE__)区别详解
2016/09/24 PHP
PHP时间戳和日期相互转换操作实例小结
2018/12/18 PHP
学习ExtJS Column布局
2009/10/08 Javascript
JQuery使用$.ajax和checkbox实现下次不在通知功能
2015/04/16 Javascript
AngularJS基础 ng-model-options 指令简单示例
2016/08/02 Javascript
Javascript 6里的4个新语法
2016/08/25 Javascript
基于touch.js手势库+zepto.js插件开发图片查看器(滑动、缩放、双击缩放)
2016/11/17 Javascript
bootstrap中添加额外的图标实例代码
2017/02/15 Javascript
Angular.JS通过指令操作DOM的方法
2017/05/10 Javascript
ES6入门教程之Class和Module详解
2017/05/17 Javascript
Vue组件实例间的直接访问实现代码
2017/08/20 Javascript
bootstrap paginator分页插件的两种使用方式实例详解
2017/11/14 Javascript
jQuery实现动态加载(按需加载)javascript文件的方法分析
2019/05/31 jQuery
JavaScript基于SVG的图片切换效果实例代码
2020/12/15 Javascript
python将多个文本文件合并为一个文本的代码(便于搜索)
2011/03/13 Python
剖析Django中模版标签的解析与参数传递
2015/07/21 Python
python使用pyqt写带界面工具的示例代码
2017/10/23 Python
手把手教你python实现SVM算法
2017/12/27 Python
使用Flask集成bootstrap的方法
2018/07/24 Python
Python实现京东秒杀功能代码
2019/05/16 Python
Python爬取微信小程序Charles实现过程图解
2020/09/29 Python
基于python的opencv图像处理实现对斑马线的检测示例
2020/11/29 Python
css3 中的新特性加强记忆详解
2016/04/16 HTML / CSS
html5给汉字加拼音加进度条的实现代码
2020/04/07 HTML / CSS
几个Shell Script面试题
2012/08/31 面试题
《一个小村庄的故事》教学反思
2014/04/13 职场文书
大学生演讲稿
2014/04/25 职场文书
搞笑车尾标语
2014/06/23 职场文书
2014年安全生产目标责任书
2014/07/23 职场文书
初中重阳节活动总结
2015/05/05 职场文书
Python带你从浅入深探究Tuple(基础篇)
2021/05/15 Python
彻底解决MySQL使用中文乱码的方法
2022/01/22 MySQL