JavaScript通过HTML的class来获取HTML元素的方法总结


Posted in Javascript onMay 24, 2016

对于js来说,我想每一个刚接触它的人都应该会抱怨:为什么没有一个通过class来获取元素的方法。尽管现在高版本的浏览器已经支持getElementsByClassName()函数,但是对于低版本浏览器来说,还是无法兼容,在脱离其他库的时候,还是得自己封装一个方法。

方法一

function getByClass1(parent, cls){
  var res = [];  //存放匹配结果的数组
  var ele = parent.getElementsByTagName('*');
  for(var i = 0; i < ele.length; i++){
    if(ele[i].className == cls){
      res.push(ele[i]);
    }
  }
  return res;
}

当然class里的值只有一个时,上面的方法没问题,但当值为多个时,就会出现问题。

<div class="test"></div>
<div class="test box"></div>
<script>
  getByClass1(document, 'test');  //只获取到第一个div
</script>

方法二

出现问题的时候,我们会尝试着改进,对于多类名的情况我们可以用正则去匹配是否包含所要查找的class名,于是就出现了下面这种写法:

function getByClass2(parent, cls){
  var res = [];
  var reg = new RegExp('\\b' + cls + '\\b', 'i');  //匹配cls是一个独立的单词
  var ele = parent.getElementsByTagName('*');
  for(var i = 0; i < ele.length; i++){
    if(reg.test(ele[i].className)){
      res.push(ele[i]);
    }
  }
  return res;
}

这种方法看似可以,解决了getByClass1()的问题,我也用了好长一段时间,但是还会有一个隐藏的bug。看下面的例子:

<div class="test"></div>
<div class="test_box"></div>
<div class="test-box"></div>
<script>
  getByClass2(document, 'test');  //结果获取到了第一个div和第三个div
</script>

理论上应该只获取到第一个,但是却和我们预期不一样。这个bug源于下面这段代码里的\b

var reg = new RegExp('\\b' + cls + '\\b', 'i');

我们先来看下\b在正则中的表示的意思

\b是正则表达式规定的一个特殊代码,代表着单词的开头或结尾,也就是单词的分界处。

通俗点说:\b就是匹配一个单词(从左边界到右边界)。

而问题也就出在这里,\b把除字母、数字、下划线外的其他字符都当成是边界,对于上面的例子中第三个class值为test-box,\b匹配时,把连字符(-)当作单词边界,所以也匹配了第三个div。

方法三

因此我们还需要对上面方法进行进一步改进,这里参考了stackoverflow上提到的一种方法:

How to Get Element By Class in JavaScript?

改进后的代码如下:

function getByClass3(parent, cls){
  var res = [];
  var reg = new RegExp(' ' + cls + ' ', 'i');  //匹配cls时,两边需要有空格
  var ele = parent.getElementsByTagName('*');
  for(var i = 0; i < ele.length; i++){
    if(reg.test(' ' + ele[i].className + ' ')){
      res.push(ele[i]);
    }
  }
  return res;
}

这种方法舍去了用\b而采用空格来匹配边界,先在获取到的className值两边加上空格,这样就保证了className里的每个值两边都会有空格,然后再用正则去匹配。

用这种方法暂时还未发现问题,但是使用时,方法中的单引号内的空格一定不能落下。

方法四

function getByClass3(parent, cls){
  var res = [];
  var reg = new RegExp('(^|\\s)' + cls + '($|\\s)', 'i');
  var ele = parent.getElementsByTagName('*');
  for(var i = 0; i < ele.length; i++){
    if(reg.test(ele[i].className)){
      res.push(ele[i]);
    }
  }
  return res;
}

空格完全用正则来处理,这样省去了空格容易落下的问题,代码也更美观精简。

那么这种方法是否就是比较完美的呢,其实不然,下面来看下更优的方案。

方法五(完美版)

文章开头已经提到,高版本的浏览器已经支持getElementsByClassName()方法。出于性能考虑,对支持的浏览器使用原生方法势必会更好。而对于低版本的浏览器使用上面的方法四。

function getByClass(parent, cls){
  if(parent.getElementsByClassName){
    return parent.getElementsByClassName(cls);
  }else{
    var res = [];
    var reg = new RegExp(' ' + cls + ' ', 'i')
    var ele = parent.getElementsByTagName('*');
    for(var i = 0; i < ele.length; i++){
      if(reg.test(' ' + ele[i].className + ' ')){
        res.push(ele[i]);
      }
    }
    return res;
  }
}

当然方法五自认为是相对较好的方案,如果有更优秀的方法欢迎留言补充。

Javascript 相关文章推荐
快速解决FusionCharts联动的中文乱码问题
Dec 04 Javascript
addEventListener 的用法示例介绍
May 07 Javascript
JavaScript里四舍五入函数round用法实例
Apr 06 Javascript
js+html5实现canvas绘制镂空字体文本的方法
Jun 05 Javascript
jquery实现简单的全选和反选功能
Jan 02 Javascript
解决微信内置浏览器返回上一页强制刷新问题方法
Feb 05 Javascript
JavaScript评论点赞功能的实现方法
Mar 13 Javascript
Vue Promise的axios请求封装详解
Aug 13 Javascript
Vue.js路由实现选项卡简单实例
Jul 24 Javascript
解决node.js含有%百分号时发送get请求时浏览器地址自动编码的问题
Nov 20 Javascript
vant中的toast层级改变操作
Nov 04 Javascript
k8s node节点重新加入master集群的实现
Feb 22 Javascript
jQuery使用中可能被XSS攻击的一些危险环节提醒
May 24 #Javascript
详解Node.js模块间共享数据库连接的方法
May 24 #Javascript
轻松掌握jQuery中wrap()与unwrap()函数的用法
May 24 #Javascript
使用jQuery中的wrap()函数操作HTML元素的教程
May 24 #Javascript
实例解析jQuery中proxy()函数的用法
May 24 #Javascript
jQuery前端开发35个小技巧
May 24 #Javascript
JS+Canvas绘制时钟效果
Aug 20 #Javascript
You might like
PHP面向对象编程快速入门
2006/10/09 PHP
PHP 递归效率分析
2009/11/24 PHP
基于Windows下Apache PHP5.3.1安装教程
2010/01/08 PHP
php遍历目录与文件夹的多种方法详解
2013/11/14 PHP
Yii2数据库操作常用方法小结
2017/05/04 PHP
prettify 代码高亮着色器google出品
2010/12/28 Javascript
用Javascript评估用户输入密码的强度(Knockout版)
2011/11/30 Javascript
nodejs入门详解(多篇文章结合)
2012/03/07 NodeJs
JavaScript调用堆栈及setTimeout使用方法深入剖析
2013/02/16 Javascript
js 表单提交后按钮变灰的实例代码
2013/08/16 Javascript
js从10种颜色中随机取色实现每次取出不同的颜色
2013/10/23 Javascript
测试IE浏览器对JavaScript的AngularJS的兼容性
2015/06/19 Javascript
JS IOS/iPhone的Safari浏览器不兼容Javascript中的Date()问题如何解决
2016/11/11 Javascript
百度搜索框智能提示案例jsonp
2016/11/28 Javascript
BootStrap 图标icon符号图标glyphicons不正常显示的快速解决办法
2016/12/08 Javascript
Vuejs 组件——props数据传递的实例代码
2017/03/07 Javascript
Angular实现一个简单的多选复选框的弹出框指令实例
2017/04/25 Javascript
基于jstree使用AJAX请求获取数据形成树
2017/08/29 Javascript
微信小程序wx.previewImage预览图片实例详解
2017/12/07 Javascript
Element-ui table中过滤条件变更表格内容的方法
2018/03/02 Javascript
vue.js绑定事件监听器示例【基于v-on事件绑定】
2018/07/07 Javascript
详解微信小程序胶囊按钮返回|首页自定义导航栏功能
2019/06/14 Javascript
为nuxt项目写一个面包屑cli工具实现自动生成页面与面包屑配置
2019/09/29 Javascript
python中的yield使用方法
2014/02/11 Python
python中sleep函数用法实例分析
2015/04/29 Python
如何用python写一个简单的词法分析器
2018/12/18 Python
Python3实现的反转单链表算法示例
2019/03/08 Python
经典c++面试题六
2012/01/18 面试题
新闻记者实习自我鉴定
2013/09/19 职场文书
小学音乐教学反思
2014/02/05 职场文书
遗嘱公证书标准样本
2014/04/08 职场文书
师德师风自查总结
2014/10/14 职场文书
2014年学校工会工作总结
2014/12/06 职场文书
团日活动总结格式
2015/05/11 职场文书
Django 如何实现文件上传下载
2021/04/08 Python
利用JuiceFS使MySQL 备份验证性能提升 10 倍
2022/03/17 MySQL