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 相关文章推荐
利用JS自动打开页面上链接的实现代码
Sep 25 Javascript
Javascript算符的优先级介绍
Mar 20 Javascript
关于innerHTML后丢失动态绑定的EVENT问题解决方法
May 19 Javascript
javascript实现锁定网页、密码解锁效果(类似系统屏幕保护效果)
Aug 15 Javascript
JavaScript中的单引号和双引号报错的解决方法
Sep 01 Javascript
jquery中toggle函数交替使用问题
Jun 22 Javascript
浅析在javascript中创建对象的各种模式
May 06 Javascript
js实现简易垂直滚动条
Feb 22 Javascript
纯js的右下角弹窗实例
Mar 12 Javascript
QRCode.js二维码生成并能长按识别
Oct 16 Javascript
使用p5.js实现动态GIF图片临摹重现
Oct 23 Javascript
vue2.x 通过后端接口代理,获取qq音乐api的数据示例
Oct 30 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
phpwind中的数据库操作类
2007/01/02 PHP
PHP实现XML与数据格式进行转换类实例
2015/07/29 PHP
php识别翻转iphone拍摄的颠倒图片
2018/05/17 PHP
JavaScript中使用构造函数实现继承的代码
2010/08/12 Javascript
jquery实现漂浮在网页右侧的qq在线客服插件示例
2013/05/13 Javascript
javascript禁制后退键(Backspace)实例代码
2013/11/15 Javascript
js获取光标位置和设置文本框光标位置示例代码
2014/01/09 Javascript
深入理解JavaScript系列(25):设计模式之单例模式详解
2015/03/03 Javascript
js实现模拟计算器退格键删除文字效果的方法
2015/05/07 Javascript
jQuery动态修改字体大小的方法【测试可用】
2016/09/09 Javascript
前端框架学习总结之Angular、React与Vue的比较详解
2017/03/14 Javascript
微信小程序 引入es6 promise
2017/04/12 Javascript
js学使用setTimeout实现轮循动画
2017/07/17 Javascript
基于jQuery实现手风琴菜单、层级菜单、置顶菜单、无缝滚动效果
2017/07/20 jQuery
javaScript实现复选框全选反选事件详解
2020/11/20 Javascript
微信小程序实现折叠面板
2018/01/31 Javascript
echarts统计x轴区间的数值实例代码详解
2019/07/07 Javascript
JavaScript本地储存:localStorage、sessionStorage、cookie的使用
2020/10/13 Javascript
[01:07:46]完美世界DOTA2联赛循环赛 Magma vs IO BO2第二场 11.01
2020/11/02 DOTA
[57:36]DOTA2-DPC中国联赛 正赛 SAG vs CDEC BO3 第三场 2月1日
2021/03/11 DOTA
Python 列表(List)操作方法详解
2014/03/11 Python
Python爬虫利用cookie实现模拟登陆实例详解
2017/01/12 Python
python仿抖音表白神器
2019/04/08 Python
Python 时间戳之获取整点凌晨时间戳的操作方法
2020/01/28 Python
Python按照list dict key进行排序过程解析
2020/04/04 Python
用python按照图像灰度值统计并筛选图片的操作(PIL,shutil,os)
2020/06/04 Python
python批量修改文件名的示例
2020/09/27 Python
css3给背景图片加颜色遮罩的方法
2019/11/05 HTML / CSS
自我评价的正确写法
2013/09/19 职场文书
高分子材料与工程专业个人求职信
2013/12/15 职场文书
运动会广播稿20字
2014/02/18 职场文书
《雕塑之美》教学反思
2014/04/24 职场文书
学校安全生产承诺书
2014/05/23 职场文书
青奥会口号
2014/06/12 职场文书
行政专员岗位职责说明书
2014/09/01 职场文书
jQuery实现影院选座订座效果
2021/04/13 jQuery