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 相关文章推荐
javascript动态加载实现方法一
Aug 22 Javascript
javascript 实现字符串反转的三种方法
Nov 23 Javascript
javascript实现图片轮播效果
Jan 20 Javascript
javascript对象的相关操作小结
May 16 Javascript
JS实现类似51job上的地区选择效果示例
Nov 17 Javascript
AngularJS入门教程之Helloworld示例
Dec 25 Javascript
React实现点击删除列表中对应项
Jan 10 Javascript
完美实现js拖拽效果 return false用法详解
Jul 28 Javascript
jquery学习笔记之无new构建详解
Dec 07 jQuery
jQuery基于随机数解决中午吃什么去哪吃问题示例
Dec 29 jQuery
ES6基础之默认参数值
Feb 21 Javascript
layer父页获取弹出层输入框里面的值方法
Sep 02 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
PHP网站安装程序制作的原理、步骤、注意事项和示例代码
2010/08/01 PHP
php连接mssql的一些相关经验及注意事项
2013/02/05 PHP
php中的路径问题与set_include_path使用介绍
2014/02/11 PHP
PHP易混淆函数的区别及用法汇总
2014/11/22 PHP
php中10个不同等级压缩优化图片操作示例
2016/11/14 PHP
Laravel框架分页实现方法分析
2018/06/12 PHP
PHP基于openssl实现的非对称加密操作示例
2019/01/11 PHP
javascript 获取图片尺寸及放大图片
2013/09/04 Javascript
javascript读取xml实现javascript分页
2013/12/13 Javascript
js写的方法实现上传图片之后查看大图
2014/03/05 Javascript
jQuery循环遍历子节点并获取值的方法
2016/04/14 Javascript
Javascript基础回顾之(三) js面向对象
2017/01/31 Javascript
小发现之浅谈location.search与location.hash的问题
2017/06/23 Javascript
jQuery简介_动力节点Java学院整理
2017/07/04 jQuery
Vue.js结合Ueditor富文本编辑器的实例代码
2017/07/11 Javascript
JS获取一个表单字段中多条数据并转化为json格式
2017/10/17 Javascript
基于jQuery中ajax的相关方法汇总(必看篇)
2017/11/08 jQuery
微信小程序实现列表下拉刷新上拉加载
2020/07/29 Javascript
深入理解Vue router的部分高级用法
2018/08/15 Javascript
微信小程序实现评论功能
2018/11/28 Javascript
JS中的一些常用的函数式编程术语
2019/06/15 Javascript
javascript 高级语法之继承的基本使用方法示例
2019/11/11 Javascript
详解vue v-model
2020/08/31 Javascript
python分割和拼接字符串
2013/11/01 Python
Python实现简单的语音识别系统
2017/12/13 Python
Python数据分析之双色球基于线性回归算法预测下期中奖结果示例
2018/02/08 Python
python实现比较类的两个instance(对象)是否相等的方法分析
2019/06/26 Python
Python及Pycharm安装方法图文教程
2019/08/05 Python
Python利用matplotlib绘制约数个数统计图示例
2019/11/26 Python
基于HTML5实现类似微信手机摇一摇功能(计算摇动次数)
2017/07/24 HTML / CSS
室内设计专业个人的自我评价
2013/10/19 职场文书
《白鹅》教学反思
2014/04/13 职场文书
歌唱比赛策划方案
2014/06/06 职场文书
要账委托书范本
2014/09/15 职场文书
2016年“5.12”护士节慰问信
2015/11/30 职场文书
2016年第32个教师节红领巾广播稿
2015/12/18 职场文书