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 相关文章推荐
根据一段代码浅谈Javascript闭包
Dec 14 Javascript
给应用部分的js代码设定一个统一的入口
Jun 15 Javascript
JavaScript设计模式之策略模式实例
Oct 10 Javascript
6种javascript显示当前系统时间代码
Dec 01 Javascript
javascript html5移动端轻松实现文件上传
Mar 27 Javascript
JavaScript中的splice方法用法详解
Jul 20 Javascript
js复制内容到剪贴板代码,js复制代码的简单实例
Oct 27 Javascript
Vue 项目部署到服务器的问题解决方法
Dec 05 Javascript
react router4+redux实现路由权限控制的方法
May 03 Javascript
Vue数据绑定实例写法
Aug 06 Javascript
jquery实现购物车基本功能
Oct 25 jQuery
Element Collapse 折叠面板的使用方法
Jul 26 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/11/23 PHP
PHP5 字符串处理函数大全
2010/03/23 PHP
微信公众号开发之微信公共平台消息回复类实例
2014/11/14 PHP
详解PHP编码转换函数应用技巧
2016/10/22 PHP
Jquery 获取表单text,areatext,radio,checkbox,select值的代码
2009/11/12 Javascript
jquery.cookie() 方法的使用(读取、写入、删除)
2013/12/05 Javascript
js简单的表格添加行和删除行操作示例
2014/03/31 Javascript
Node.js环境下JavaScript实现单链表与双链表结构
2016/06/12 Javascript
深入浅析JavaScript中的scrollTop
2016/07/11 Javascript
最原始的jQuery注册验证方式
2016/10/11 Javascript
基于vue.js路由参数的实例讲解——简单易懂
2017/09/07 Javascript
jQuery EasyUI 选项卡面板tabs的使用实例讲解
2017/12/25 jQuery
Vue仿支付宝支付功能
2018/05/25 Javascript
layui前端框架之table表数据的刷新方法
2018/08/17 Javascript
vue中子组件的methods中获取到props中的值方法
2018/08/27 Javascript
使用iView Upload 组件实现手动上传图片的示例代码
2018/10/01 Javascript
vue如何根据网站路由判断页面主题色详解
2018/11/02 Javascript
js实现倒计时秒杀效果
2020/03/25 Javascript
微信小程序实现一个简单swiper代码实例
2019/12/30 Javascript
vue 解决在微信内置浏览器中调用支付宝支付的情况
2020/11/09 Javascript
小程序组件传值和引入sass的方法(使用vant Weapp组件库)
2020/11/24 Javascript
[01:03:41]DOTA2-DPC中国联赛 正赛 Dynasty vs XG BO3 第三场 2月2日
2021/03/11 DOTA
python实现监控windows服务并自动启动服务示例
2014/04/17 Python
理解python多线程(python多线程简明教程)
2014/06/09 Python
Python双向循环链表实现方法分析
2018/07/30 Python
python三方库之requests的快速上手
2019/03/04 Python
通过python改变图片特定区域的颜色详解
2019/07/15 Python
python中树与树的表示知识点总结
2019/09/14 Python
英国第一蛋白粉品牌:Myprotein
2016/09/14 全球购物
经贸日语专业个人求职信范文
2013/12/28 职场文书
企业消防安全制度
2014/02/02 职场文书
关于五一放假的通知
2015/08/18 职场文书
实验心得体会范文
2016/01/25 职场文书
市语委办2016年第十九届“推普周”活动总结
2016/04/05 职场文书
七年级作文之下雨天
2019/12/23 职场文书
MySQL池化框架学习接池自定义
2022/07/23 MySQL