作家
登录

javascript getElementsByClassName实现代码

作者: 来源:www.28hudong.com 2013-03-30 01:16:37 阅读 我要评论

先来看一下代码:(支持多个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); 好了,不多说的,这个函数简单实用,代码上我也写了注释,看明白应该已经没有什么问题了

  推荐阅读

  Tips 带三角可关闭的文字提示

Tips,带三角可关闭的文字提示 body{ font-size:12px;} .lj-tipsWrap,.lj-in,.lj-close{display:inline-block;} .lj-tipsWrap{background:#F4FBFF;line-height:1.5em;padding:5px 15px;border:>>>详细阅读


本文标题:javascript getElementsByClassName实现代码

地址:http://www.17bianji.com/kaifa2/JS/25644.html

关键词: 探索发现

乐购科技部分新闻及文章转载自互联网,供读者交流和学习,若有涉及作者版权等问题请及时与我们联系,以便更正、删除或按规定办理。感谢所有提供资讯的网站,欢迎各类媒体与乐购科技进行文章共享合作。

网友点评
自媒体专栏

评论

热度

精彩导读
栏目ID=71的表不存在(操作类型=0)