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脚本性能的优化方法
Feb 02 Javascript
JQuery 应用 JQuery.groupTable.js
Dec 15 Javascript
jquery获取下拉列表的值为null的解决方法
Mar 18 Javascript
javascript数字格式化通用类 accounting.js使用
Aug 24 Javascript
JS交换变量的方法
Jan 21 Javascript
EasyUI的doCellTip实现鼠标放到单元格上提示单元格内容
Aug 24 Javascript
Iscrool下拉刷新功能实现方法(推荐)
Jun 26 Javascript
解决element UI 自定义传参的问题
Aug 22 Javascript
javascript实现自由编辑图片代码详解
Jun 21 Javascript
javascript 代码是如何被压缩的示例代码
May 06 Javascript
vue-cli中实现响应式布局的方法
Mar 02 Vue.js
详细聊聊浏览器是如何看闭包的
Nov 11 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递归实现无限分类生成下拉列表的函数
2010/08/08 PHP
php通过记录IP来防止表单重复提交方法分析
2014/12/16 PHP
PHP IDE phpstorm 常用快捷键
2015/05/18 PHP
PHP程序中的文件锁、互斥锁、读写锁使用技巧解析
2016/03/21 PHP
Thinkphp和Bootstrap结合打造个性的分页样式(推荐)
2016/08/01 PHP
PHP调用全国天气预报数据接口查询天气示例
2019/02/20 PHP
Mootools 1.2 手风琴(Accordion)教程
2009/09/15 Javascript
JavaScript中各种编码解码函数的区别和注意事项
2010/08/19 Javascript
分享27个jQuery 表单插件集合推荐
2011/04/25 Javascript
取得元素的左和上偏移量的方法
2014/09/17 Javascript
IE7浏览器窗口大小改变事件执行多次bug及IE6/IE7/IE8下resize问题
2015/08/21 Javascript
JavaScript中字符串与Unicode编码互相转换的实现方法
2015/12/18 Javascript
jQuery实现的简单分页示例
2016/06/01 Javascript
JS阻止事件冒泡行为和闭包的方法
2016/06/16 Javascript
JSON与js对象序列化实例详解
2017/03/16 Javascript
使用js获取伪元素的content实例
2017/10/24 Javascript
React Native 截屏组件的示例代码
2017/12/06 Javascript
Vue实现table上下移动功能示例
2019/02/21 Javascript
详解vue开发中调用微信jssdk的问题
2019/04/16 Javascript
前端插件之Bootstrap Dual Listbox使用教程
2019/07/23 Javascript
使用优化器来提升Python程序的执行效率的教程
2015/04/02 Python
python自动zip压缩目录的方法
2015/06/28 Python
使用python进行文本预处理和提取特征的实例
2018/06/05 Python
python安装virtualenv虚拟环境步骤图文详解
2019/09/18 Python
法国票务网站:Ticketmaster法国
2018/07/09 全球购物
VisionPros美国站:加拿大在线隐形眼镜和眼镜零售商
2020/02/11 全球购物
用C#语言写出在本地创建一个UDP接收端口的具体过程
2016/02/22 面试题
vue 中 get / delete 传递数组参数方法
2021/03/23 Vue.js
求职推荐信
2013/10/28 职场文书
揠苗助长教学反思
2014/02/04 职场文书
任命书怎么写
2014/06/04 职场文书
运动会演讲稿300字
2014/08/25 职场文书
员工教育培训协议书
2014/09/27 职场文书
2014年民主评议党员工作总结
2014/12/02 职场文书
2015年新教师个人工作总结
2015/10/14 职场文书
python文本处理的方案(结巴分词并去除符号)
2021/05/26 Python