javascript getElementsByClassName实现代码


Posted in Javascript onOctober 11, 2010

先来看一下代码:(支持多个class查询和在某个范围内进行查询)

/* 
* 根据元素clsssName得到元素集合 
* @param fatherId 父元素的ID,默认为document 
* @tagName 子元素的标签名 
* @className 用空格分开的className字符串 
*/ 
function getElementsByClassName(fatherId,tagName,className){ 
node = fatherId&&document.getElementById(fatherId) || document; 
tagName = tagName || "*"; 
className = className.split(" "); 
var classNameLength = className.length; 
for(var i=0,j=classNameLength;i<j;i++){ 
//创建匹配类名的正则 
className[i]= new RegExp("(^|\\s)" + className[i].replace(/\-/g, "\\-") + "(\\s|$)"); 
} 
var elements = node.getElementsByTagName(tagName); 
var result = []; 
for(var i=0,j=elements.length,k=0;i<j;i++){//缓存length属性 
var element = elements[i]; 
while(className[k++].test(element.className)){//优化循环 
if(k === classNameLength){ 
result[result.length] = element; 
break; 
} 
} 
k = 0; 
} 
return result; 
}

好,我们来测试一下:
<div id="container"> 
<span class="aaa zzz ccc"></span> 
<div class="aaa bbb ccc"></div> 
</div> 
<div class="aaa bbb ccc"></div>

window.onload = function(){ 
alert(getElementsByClassName(document,"div","aaa ccc").length);//2 
alert(getElementsByClassName("container","div","aaa ccc").length);//1 
alert(getElementsByClassName("container","span","aaa zzz").length);//1 
}

正确的得到了结果。
原生的getElementsByClassName
有人会问,原生的方法调用效率是最高的,有很多浏览器已经将实现了getElementsByClassName这个方法,那为什这里没有先调用原生的再调用自定义的呢?
对,原生的效率是很高,它支持多个class条件的查询,但是最大的问题是他不支持getElementsByClassName("container","div","aaa ccc"),这种在指定标签中查找指定元素为指定class的情况。
所以,这里舍弃了原生的方法调用。
关于循环优化的问题
在代码中,你会看到我将数组的length缓存了起来,这样可以提高效率。其实上,在这里有一个很隐蔽的问题,就是数组访问length属性和HtmlCollection访问length有很在的区别。在数组中,length是一个普通的属性,访问时不会进行额外的操作,在来看看HTMLCollection,我们常常将HTMLCollection当作数组来使用,但实际上,它是一个根据DOM结构自动变化的实体对象。每次访问一个HTMLCollection对象的属性时,他都会对DOM内所有的节点进行一次完整的匹配。也就是说,每次访问HtmlCollection对象的length时,都会更新一次集合对象,性能上消耗很大。所以一般情况之下,这种HtmlCollection的循环操作,都是建议缓存length的。
额外的收获
这是关于往数组里放元素的方式间,效率比较的问题
来看一下代码:
//方式一 
var arr = []; 
var start = new Date(); 
for(var i=0;i<100000;i++){ 
arr.push(i); 
} 
//方式二 
var arr = []; 
var start = new Date(); 
for(var i=0;i<100000;i++){ 
arr[arr.length]=i; 
}

猜猜看,哪种效率更高呢!经过测试,第二种方式的效率要高于第一种。
提醒:
这个版本是不兼容IE5的,以下是我给出的解释:
1.当你从那千分之几的统计数据里,再去疯钱的IE5测试人员的点击和专业程序员对IE5的好奇心,估计就只剩IE5被焚烧后的灰烬了。
2.你要想信灰烬的利用价值趋于零
3.如果到现在还没能说服你,那我想说,你很专业!即然这样,那还有IE3,IE2,IE?FF1,NN4...,我想你应该一并实现了。
一些坦白:我也不怎么说服得了我自已,唉,还是给一个IE5的解决方案吧:
IE5并不支持getElementByTagName("*")的形式,所以在这里要处理一下:
var elements = (tagName==='*'&&node.all)?node.all:node.getElementsByTagName(tagName);
好了,不多说的,这个函数简单实用,代码上我也写了注释,看明白应该已经没有什么问题了
Javascript 相关文章推荐
js tab效果的实现代码
Dec 26 Javascript
jquery调用wcf并展示出数据的方法
Jul 07 Javascript
jquery入门—访问DOM对象方法
Jan 07 Javascript
JavaScript通过this变量快速找出用户选中radio按钮的方法
Mar 23 Javascript
jQuery实现拖拽效果插件的方法
Mar 23 Javascript
JavaScript驾驭网页-CSS与DOM
Mar 24 Javascript
JS实现的幻灯片切换显示效果
Sep 07 Javascript
jQuery简单实现列表隐藏和显示效果示例
Sep 12 Javascript
JS产生随机数的用法小结
Dec 10 Javascript
swiper 解决动态加载数据滑动失效的问题
Feb 26 Javascript
微信小程序一周时间表功能实现
Oct 17 Javascript
Node在Controller层进行数据校验的过程详解
Aug 28 Javascript
javascript Array.prototype.slice使用说明
Oct 11 #Javascript
javascript 伪数组实现方法
Oct 11 #Javascript
javascript forEach通用循环遍历方法
Oct 11 #Javascript
JavaScript 操作键盘的Enter事件(键盘任何事件),兼容多浏览器
Oct 11 #Javascript
JavaScript isArray()函数判断对象类型的种种方法
Oct 11 #Javascript
JSChart轻量级图形报表工具(内置函数中文参考)
Oct 11 #Javascript
jQuery 表单验证扩展代码(一)
Oct 11 #Javascript
You might like
点评山进PR-D3L三波段收音机
2021/03/02 无线电
php中将时间差转换为字符串提示的实现代码
2011/08/08 PHP
YII路径的用法总结
2014/07/09 PHP
php实现给一张图片加上水印效果
2016/01/02 PHP
Yii框架应用组件用法实例分析
2020/05/15 PHP
15款优秀的jQuery导航菜单插件分享
2011/07/19 Javascript
JS TextArea字符串长度限制代码集合
2012/10/31 Javascript
javascript面向对象包装类Class封装类库剖析
2013/01/24 Javascript
在JavaScript中实现类的方式探讨
2013/08/28 Javascript
页面按钮禁用与解除禁用的方法
2014/02/19 Javascript
使用js实现数据格式化
2014/12/03 Javascript
jQuery实现的放大镜效果示例
2016/09/13 Javascript
Javascript 引擎工作机制详解
2016/11/30 Javascript
JS焦点图,JS 多个页面放多个焦点图的实例
2016/12/08 Javascript
javaScript基础详解
2017/01/19 Javascript
bootstrap的常用组件和栅格式布局详解
2017/05/02 Javascript
Angular2 之 路由与导航详细介绍
2017/05/26 Javascript
JavaScript模拟文件拖选框样式v1.0的实例
2017/08/04 Javascript
聊聊那些使用前端Javascript实现的机器学习类库
2017/09/18 Javascript
node实现基于token的身份验证
2018/04/09 Javascript
关于js对textarea换行符的处理方法浅析
2018/08/03 Javascript
[05:56]第十六期——新进3大C之小兔基
2014/06/24 DOTA
零基础写python爬虫之抓取百度贴吧并存储到本地txt文件改进版
2014/11/06 Python
收藏整理的一些Python常用方法和技巧
2015/05/18 Python
Python + selenium自动化环境搭建的完整步骤
2018/05/19 Python
Django使用paginator插件实现翻页功能的实例
2018/10/24 Python
Django shell调试models输出的SQL语句方法
2019/08/29 Python
tensorflow实现测试时读取任意指定的check point的网络参数
2020/01/21 Python
拉飞逸官网:Lafayette 148 New York
2020/07/15 全球购物
找工作最新求职信
2013/12/22 职场文书
爽歪歪广告词
2014/03/20 职场文书
小学教师见习总结
2015/06/23 职场文书
使用react+redux实现计数器功能及遇到问题
2021/06/02 Javascript
适合后台管理系统开发的12个前端框架(小结)
2021/06/29 Javascript
javascript之Object.assign()的痛点分析
2022/03/03 Javascript
javascript中Set、Map、WeakSet、WeakMap区别
2022/12/24 Javascript