对于js来说,我想每一个刚接触它的人都应该会抱怨:为什么没有一个通过class来获取元素的方法。尽管现在高版本的浏览器已经支持getElementsByClassName()方法,但是对于低版本浏览器来说,还是无法兼容,在脱离其他库的时候,还是得自己封装一个方法。
也可到独立博客查看:getByClass()函数进化史
下面列举几种网上常见的方法并说明存在的一些问题。
方法一
function getByClass1(oParent, sClass){
var aRes = []; //存放匹配结果的数组
var aEle = oParent.getElementsByTagName('*');
for(var i = 0; i < aEle.length; i++){
if(aEle[i].className == sClass){
aRes.push(aEle[i]);
}
}
return aRes;
}
当然class里的值只有一个时,上面的方法没问题,但当值为多个时,就会出现问题。
<div class="test"></div>
<div class="test box"></div>
<script>
getByClass1(document, 'test'); //只获取到第一个div
</script>
方法二
出现问题的时候,我们会尝试着改进,对于多类名的情况我们可以用正则去匹配是否包含所要查找的class名,于是就出现了下面这种写法:
function getByClass2(oParent, sClass){
var aRes = [];
var re = new RegExp('\\b' + sClass + '\\b', 'i'); //匹配sClass是一个独立的单词
var aEle = oParent.getElementsByTagName('*');
for(var i = 0; i < aEle.length; i++){
if(re.test(aEle[i].className)){
aRes.push(aEle[i]);
}
}
return aRes;
}
这种方法看似可以,解决了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 re = new RegExp('\\b' + sClass + '\\b', 'i');
我们先来看下\b在正则中的表示的意思
\b是正则表达式规定的一个特殊代码,代表着单词的开头或结尾,也就是单词的分界处。
通俗点说:\b就是匹配一个单词(从左边界到右边界)。
而问题也就出在这里,\b把除字母、数字、下划线外的其他字符都当成是边界,对于上面的例子中第三个class值为test-box,\b匹配时,把连字符(-)当作单词边界,所以也匹配了第三个div。
方法三
因此我们还需要对上面方法进行进一步改进,这里参考了stackoverflow上提到的一种方法:
How to Get Element By Class in JavaScript?
改进后的代码如下:
function getByClass3(oParent, sClass){
var aRes = [];
var re = new RegExp(' ' + sClass + ' ', 'i'); //匹配sClass时,两边需要有空格
var aEle = oParent.getElementsByTagName('*');
for(var i = 0; i < aEle.length; i++){
if(re.test(' ' + aEle[i].className + ' ')){
aRes.push(aEle[i]);
}
}
return aRes;
}
这种方法舍去了用\b而采用空格来匹配边界,先在获取到的className值两边加上空格,这样就保证了className里的每个值两边都会有空格,然后再用正则去匹配。
用这种方法暂时还未发现问题,但是使用时,方法中的单引号内的空格一定不能落下。
方法四
继续改进:
function getByClass3(oParent, sClass){
var aRes = [];
var re = new RegExp('(^|\\s)' + sClass + '($|\\s)', 'i');
var aEle = oParent.getElementsByTagName('*');
for(var i = 0; i < aEle.length; i++){
if(re.test(aEle[i].className)){
aRes.push(aEle[i]);
}
}
return aRes;
}
空格完全用正则来处理,这样省去了空格容易落下的问题,代码也更美观精简。
那么这种方法是否就是比较完美的呢,其实不然,下面来看下更优的方案。
方法五(完美版)
文章开头已经提到,高版本的浏览器已经支持getElementsByClassName()方法。出于性能考虑,对支持的浏览器使用原生方法势必会更好。而对于低版本的浏览器使用上面的方法四。
function getByClass(oParent, sClass){
if(oParent.getElementsByClassName){
return oParent.getElementsByClassName(sClass);
}else{
var aRes = [];
var re = new RegExp('(^|\\s)' + sClass + '($|\\s)', 'i');
var aEle = oParent.getElementsByTagName('*');
for(var i = 0; i < aEle.length; i++){
if(re.test(aEle[i].className)){
aRes.push(aEle[i]);
}
}
return aRes;
}
}
当然方法五自认为是相对较好的方案,如果有更优秀的方法欢迎留言补充。
分享到:
相关推荐
在JavaScript编程中,有时会遇到需要根据函数名的字符串形式来动态执行对应函数的场景。这类技术能够提供一种灵活的方式来执行代码,尤其在进行插件化开发、事件驱动编程或实现钩子函数时非常有用。为了实现这一功能...
3. **数组和集合**:学习JavaScript中的数组操作,如map、filter、reduce等高阶函数的运用,以及Set和Map等ES6新增集合类型的使用。 4. **函数**:理解闭包、作用域和this的关键概念,学习箭头函数的语法和特性。 5....
- 为了提高可读性和可维护性,推荐将复杂的JavaScript逻辑放在独立的.js文件中,然后通过`<script src="...">`引用。 - 传递敏感数据时要格外小心,可能需要加密或使用安全的传输层协议(如HTTPS)。 5. **示例**...
标题“javascript调用delphi中的函数”涉及到的技术领域是跨语言通信,具体是JavaScript与Delphi之间的交互。这种交互通常发生在Web应用程序与桌面应用程序的集成,或者在浏览器扩展和本地资源之间。以下是对这一...
总结而言,JS函数式编程指南为读者提供了一种途径,借助于JavaScript这种广泛使用的编程语言,去理解和掌握函数式编程的核心概念和实践技巧。这本指南不仅涵盖了函数式编程的基础理论,还详细介绍了如何在实际开发中...
不过,由于【标题】中提供了文档的名称——"JavaScript函数式编程.pdf",我可以根据这个名称扩展出关于JavaScript函数式编程的知识点。 JavaScript函数式编程的知识点非常丰富,涉及很多方面的内容,下面将详细介绍...
JavaScript 中 eval 函数的用法 JavaScript 中的 eval 函数是一个非常强大且灵活的函数,可以将一个字符串当作一个 JavaScript 表达式来执行。正如我们在上面的描述中所看到的,eval 函数可以将一个字符串解释成 ...
3. **闭包**:闭包是JavaScript中的一个关键特性,它允许函数访问并操作其词法作用域内的变量,即使该函数在其外部被调用。闭包常用于实现私有变量和模块化。 4. **柯里化(Currying)**:柯里化是将接受多个参数的...
本文将深入探讨如何在QT应用中与网页内的JavaScript函数进行交互,使得桌面应用能够利用Web技术增强其交互性和动态性。 实现QT和JavaScript的互调,主要依赖于QT的QWebEngine模块,它提供了对Web内容的渲染和交互...
JavaScript中的函数是编程的核心部分,它允许我们定义可重复使用的代码块,以便在需要时调用。本教程将深入探讨JS函数的基础知识,通过实际案例帮助理解其工作原理。 一、函数定义 在JavaScript中,我们可以使用`...
js原生态函数中使用jQuery中的$(this)无效的解决方法 在JavaScript开发中,使用jQuery的$(this)在原生态函数中可能会出现无效的问题,本文将对此进行详细的分析和解决方法的介绍。 一、问题描述 在JavaScript开发...
以上内容是JavaScript中的基本概念,对于压缩包中的"js面向对象--多态"这个文件名,可以推测博客可能详细讨论了JavaScript如何实现面向对象编程,特别是多态性这一重要特性。通过学习这些知识点,开发者能够更好地...
本压缩包“JavaScript学习笔记_js常用函数封装_js包.zip”包含了对JavaScript基础及进阶技巧的学习资料,特别关注了函数封装和模块化开发实践。 首先,`tool.js`可能是一个实用工具函数集合,封装了一些常见的...
### 理解和使用 JavaScript 中的回调函数 在 JavaScript 中,回调函数是一种常见的功能编程技术,被广泛应用于各种场景之中。本文旨在深入探讨回调函数的概念、工作原理以及如何在实际开发中应用它们。 #### 一、...
一些js的扩展函数 一些js的扩展函数 一些js的扩展函数 一些js的扩展函数
在JavaScript中,有两种常见的延时函数:`setTimeout()` 和 `setInterval()`。然而,给定的代码片段展示了一种不同的延时方法,它通过循环检测当前时间与初始时间的差值来实现延迟效果。这种方法虽然能够达到目的,...
在JavaScript (JS) 和浏览器插件的交互中,NPAPI(Netscape Plugin Application Programming Interface)是一种早期且广泛使用的插件技术,它允许浏览器加载和运行外部代码来扩展其功能。NPAPI插件通常用于播放视频...
### JS函数式编程指南 #### 引言 函数式编程是一种编程范式,它强调使用纯函数和不可变数据结构来进行软件开发。本指南旨在帮助读者深入理解函数式编程的基本概念及其在JavaScript中的应用。 #### 第1章: 我们在...
JavaScript 中的匿名函数是一种灵活的对象,它们没有函数名,然而它们的应用场景却非常广泛。本文将对 JavaScript 匿名函数的定义、创建、调用方式、闭包的概念等进行详细的介绍。 一、函数的定义 在 JavaScript ...
### JavaScript中的匿名函数 在JavaScript编程语言中,**匿名函数**是一种非常实用且常见的特性,它们没有具体的名称,通常作为参数传递给其他函数或者在需要函数作为值的地方使用。这种类型的函数可以增加代码的...