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 相关文章推荐
jquery入门—访问DOM对象方法
Jan 07 Javascript
Javascript判断对象是否相等实现代码
Mar 18 Javascript
使用JavaScript 实现对象 匀速/变速运动的方法
May 08 Javascript
jQuery中delegate与on的用法与区别示例介绍
Dec 20 Javascript
利用jquery.qrcode在页面上生成二维码且支持中文
Feb 12 Javascript
jQuery trigger()方法用法介绍
Jan 13 Javascript
jQuery判断checkbox选中状态
May 12 Javascript
easyui combotree加载静态数据问题(选不上)解决方法
Dec 26 Javascript
layui弹出层效果实现代码
May 19 Javascript
微信小程序新增的拖动组件movable-view使用教程
May 20 Javascript
Node.js Event Loop各阶段讲解
Mar 08 Javascript
如何写好一个vue组件,老夫的一年经验全在这了(推荐)
May 18 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实现MySQL更新记录的代码
2008/06/07 PHP
php模板中出现空行解决方法
2011/03/08 PHP
PHP采用XML-RPC构造Web Service实例教程
2014/07/16 PHP
PHP中使用Imagick实现各种图片效果实例
2015/01/21 PHP
php实时倒计时功能实现方法详解
2017/02/27 PHP
Yii框架实现的验证码、登录及退出功能示例
2017/05/20 PHP
PHP笛卡尔积实现算法示例
2018/07/30 PHP
JS 自定义带默认值的函数
2011/07/21 Javascript
JS实现遮罩层效果的简单实例
2013/11/12 Javascript
深入讲解AngularJS中的自定义指令的使用
2015/06/18 Javascript
Nodejs中 npm常用命令详解
2016/07/04 NodeJs
基于jQuery实现左侧菜单栏可折叠功能
2016/12/27 Javascript
vue.js加载新的内容(实例代码)
2017/06/01 Javascript
微信小程序引用公共js里的方法的实例详解
2017/08/17 Javascript
详解基于Vue cli生成的Vue项目的webpack4升级
2018/06/19 Javascript
利用JavaScript缓存远程窃取Wi-Fi密码的思路详解
2018/11/05 Javascript
JS实现滚动条触底加载更多
2019/09/19 Javascript
javascript局部自定义鼠标右键菜单
2020/12/08 Javascript
[04:27]DOTA2官方论坛水友赛集锦
2013/09/16 DOTA
微信跳一跳游戏python脚本
2020/04/01 Python
python3中函数参数的四种简单用法
2018/07/09 Python
python将pandas datarame保存为txt文件的实例
2019/02/12 Python
python用tkinter实现一个简易能进行随机点名的界面
2020/09/27 Python
分享一枚pycharm激活码适用所有pycharm版本我的pycharm2020.2.3激活成功
2020/11/20 Python
DELPHI面试题研发笔试试卷
2015/11/08 面试题
新闻专业个人自我评价
2013/09/21 职场文书
学生自我鉴定范文
2013/10/04 职场文书
年终考核实施方案
2014/05/26 职场文书
局机关干部群众路线个人对照检查材料思想汇报
2014/10/05 职场文书
教师批评与自我批评心得体会
2014/10/16 职场文书
2014年党员整改措施
2014/10/24 职场文书
酒店总经理岗位职责
2015/04/01 职场文书
给老婆的保证书怎么写
2015/05/08 职场文书
付款证明格式范文
2015/06/19 职场文书
Pycharm连接远程服务器并远程调试的全过程
2021/06/24 Python
Python+腾讯云服务器实现每日自动健康打卡
2021/12/06 Python