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 ajax serialize()方法的使用以及常见问题解决
Jan 27 Javascript
js获取dom的高度和宽度(可见区域及部分等等)
Jun 13 Javascript
JavaScript关闭当前页面(窗口)不带任何提示
Mar 26 Javascript
node.js中的fs.lchmod方法使用说明
Dec 16 Javascript
Vue中的混入的使用(vue mixins)
Jun 01 Javascript
jQuery AJAX 方法success()后台传来的4种数据详解
Aug 08 jQuery
详解webpack之图片引入-增强的file-loader:url-loader
Oct 08 Javascript
微信小程序学习笔记之目录结构、基本配置图文详解
Mar 28 Javascript
JavaScript多种页面刷新方法小结
Apr 04 Javascript
了解javascript中变量及函数的提升
May 27 Javascript
小程序实现图片预览裁剪插件
Nov 22 Javascript
判断JavaScript中的两个变量是否相等的操作符
Dec 21 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新建文件自动编号的思路与实现
2011/06/27 PHP
php获取客户端电脑屏幕参数的方法
2015/01/09 PHP
php递归删除指定文件夹的方法小结
2015/04/20 PHP
实现laravel 插入操作日志到数据库的方法
2019/10/11 PHP
javascript 获取网页参数系统
2008/07/19 Javascript
IE6,IE7,IE8下使用Javascript记录光标选中范围(已补全)
2011/08/28 Javascript
javascript模块化简单解析
2016/04/07 Javascript
node.js 动态执行脚本
2016/06/02 Javascript
简单实现js页面切换功能
2021/01/10 Javascript
利用js判断手机是否安装某个app的多种方案
2017/02/13 Javascript
使用ionic播放轮询广告的实现方法(必看)
2017/04/24 Javascript
解决axios post 后端无法接收数据的问题
2019/10/29 Javascript
JavaScript ES6 Class类实现原理详解
2020/05/08 Javascript
[03:12]完美世界DOTA2联赛PWL DAY6集锦
2020/11/05 DOTA
python处理json数据中的中文
2014/03/06 Python
Python Tkinter基础控件用法
2014/09/03 Python
在Python中使用base64模块处理字符编码的教程
2015/04/28 Python
Python实现求解括号匹配问题的方法
2018/04/17 Python
详解Django中六个常用的自定义装饰器
2018/07/04 Python
Python根据当前日期取去年同星期日期
2019/04/14 Python
python获取Linux发行版名称
2019/08/30 Python
Python之数据序列化(json、pickle、shelve)详解
2019/08/30 Python
python sitk.show()与imageJ结合使用常见的问题
2020/04/20 Python
Python如何将函数值赋给变量
2020/04/28 Python
利用Python中的Xpath实现一个在线汇率转换器
2020/09/09 Python
英国旅游额外服务市场领导者:Holiday Extras(机场停车场、酒店、接送等)
2017/10/07 全球购物
微软台湾官方网站:Microsoft台湾
2018/08/15 全球购物
维氏瑞士军刀英国网站:Victorinox英国
2019/07/04 全球购物
4s客服专员岗位职责
2013/12/01 职场文书
捐款倡议书范文
2014/02/02 职场文书
《浅水洼里的小鱼》听课反思
2014/02/28 职场文书
工作目标责任书
2014/07/23 职场文书
出资证明书范本(标准版)
2014/09/24 职场文书
教师党的群众路线教育实践活动学习笔记
2014/11/05 职场文书
办公室主任岗位竞聘书
2015/09/15 职场文书
Redis Lua脚本实现ip限流示例
2022/07/15 Redis