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 Firefox3.5中操作select的问题
Jul 10 Javascript
JavaScript 大数据相加的问题
Aug 03 Javascript
javascript倒计时功能实现代码
Jun 07 Javascript
得到jQuery detach()后节点中的某个值实现代码
Feb 05 Javascript
javascript实现通过表格绘制颜色填充矩形的方法
Apr 21 Javascript
.NET微信公众号开发之创建自定义菜单
Jul 16 Javascript
使用jQuery监听DOM元素大小变化
Feb 24 Javascript
Javascript 普通函数和构造函数的区别
Nov 05 Javascript
jquery+css实现下拉列表功能
Sep 03 jQuery
基于node下的http小爬虫的示例代码
Jan 11 Javascript
深入理解 Koa 框架中间件原理
Oct 18 Javascript
Element Tooltip 文字提示的使用示例
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实现可用于mysql,mssql,pg数据库操作类
2014/12/13 PHP
php实现专业获取网站SEO信息类实例
2015/04/02 PHP
详解WordPress中用于更新和获取用户选项数据的PHP函数
2016/03/08 PHP
PHP QRCODE生成彩色二维码的方法
2016/05/19 PHP
thinkphp3.x连接mysql数据库的方法(具体操作步骤)
2016/05/19 PHP
Linux服务器下PHPMailer发送邮件失败的问题解决
2017/03/04 PHP
鼠标经过tr时,改变tr当前背景颜色
2014/01/13 Javascript
javascript实现简单的贪吃蛇游戏
2015/03/31 Javascript
Jquery实现瀑布流布局(备有详细注释)
2015/07/31 Javascript
jQuery多文件异步上传带进度条实例代码
2016/08/16 Javascript
前端面试题及答案整理(二)
2016/08/26 Javascript
JavaScript String(字符串)对象的简单实例(推荐)
2016/08/31 Javascript
js实现模糊匹配功能
2017/02/15 Javascript
create-react-app构建项目慢的解决方法
2018/03/14 Javascript
详解Axios 如何取消已发送的请求
2018/10/20 Javascript
JavaScript实现多张图片放大镜效果示例【不限定图片尺寸,rem单位】
2019/05/14 Javascript
Vue+Element UI+vue-quill-editor富文本编辑器及插入图片自定义
2019/08/20 Javascript
vuejs实现下拉框菜单选择
2020/10/23 Javascript
[03:40]DOTA2亚洲邀请赛小组赛第二日 赛事回顾
2015/01/31 DOTA
python网络编程实例简析
2014/09/26 Python
Python 爬取携程所有机票的实例代码
2018/06/11 Python
便捷提取python导入包的属性方法
2018/10/15 Python
Django框架自定义session处理操作示例
2019/05/27 Python
12个步骤教你理解Python装饰器
2019/07/01 Python
对python中assert、isinstance的用法详解
2019/11/27 Python
python 计算方位角实例(根据两点的坐标计算)
2020/01/17 Python
什么是python的必选参数
2020/06/21 Python
澳大利亚领先的女帽及配饰公司:Morgan&Taylor
2019/12/01 全球购物
大学生水文观测实习自我鉴定
2013/09/29 职场文书
开业庆典策划方案
2014/02/18 职场文书
安全保证书
2015/01/16 职场文书
2015毕业生简历自我评价
2015/03/02 职场文书
费城故事观后感
2015/06/10 职场文书
餐厅开业活动方案
2019/07/08 职场文书
仅用几行Python代码就能复制她的U盘文件?
2021/06/26 Python
《艾尔登法环》1.03.3补丁上线 碎星伤害调整
2022/04/06 其他游戏