javascript getElementsByClassName實(shí)現(xiàn)代碼
更新時(shí)間:2010年10月11日 22:49:01 作者:
根據(jù)元素clsssName得到元素集合的函數(shù),需要的朋友可以參考下。
先來看一下代碼:(支持多個(gè)class查詢和在某個(gè)范圍內(nèi)進(jìn)行查詢)
/*
* 根據(jù)元素clsssName得到元素集合
* @param fatherId 父元素的ID,默認(rèn)為document
* @tagName 子元素的標(biāo)簽名
* @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++){
//創(chuàng)建匹配類名的正則
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)){//優(yōu)化循環(huán)
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
}
正確的得到了結(jié)果。
原生的getElementsByClassName
有人會(huì)問,原生的方法調(diào)用效率是最高的,有很多瀏覽器已經(jīng)將實(shí)現(xiàn)了getElementsByClassName這個(gè)方法,那為什這里沒有先調(diào)用原生的再調(diào)用自定義的呢?
對,原生的效率是很高,它支持多個(gè)class條件的查詢,但是最大的問題是他不支持getElementsByClassName("container","div","aaa ccc"),這種在指定標(biāo)簽中查找指定元素為指定class的情況。
所以,這里舍棄了原生的方法調(diào)用。
關(guān)于循環(huán)優(yōu)化的問題
在代碼中,你會(huì)看到我將數(shù)組的length緩存了起來,這樣可以提高效率。其實(shí)上,在這里有一個(gè)很隱蔽的問題,就是數(shù)組訪問length屬性和HtmlCollection訪問length有很在的區(qū)別。在數(shù)組中,length是一個(gè)普通的屬性,訪問時(shí)不會(huì)進(jìn)行額外的操作,在來看看HTMLCollection,我們常常將HTMLCollection當(dāng)作數(shù)組來使用,但實(shí)際上,它是一個(gè)根據(jù)DOM結(jié)構(gòu)自動(dòng)變化的實(shí)體對象。每次訪問一個(gè)HTMLCollection對象的屬性時(shí),他都會(huì)對DOM內(nèi)所有的節(jié)點(diǎn)進(jìn)行一次完整的匹配。也就是說,每次訪問HtmlCollection對象的length時(shí),都會(huì)更新一次集合對象,性能上消耗很大。所以一般情況之下,這種HtmlCollection的循環(huán)操作,都是建議緩存length的。
額外的收獲
這是關(guān)于往數(shù)組里放元素的方式間,效率比較的問題
來看一下代碼:
//方式一
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;
}
猜猜看,哪種效率更高呢!經(jīng)過測試,第二種方式的效率要高于第一種。
提醒:
這個(gè)版本是不兼容IE5的,以下是我給出的解釋:
1.當(dāng)你從那千分之幾的統(tǒng)計(jì)數(shù)據(jù)里,再去瘋錢的IE5測試人員的點(diǎn)擊和專業(yè)程序員對IE5的好奇心,估計(jì)就只剩IE5被焚燒后的灰燼了。
2.你要想信灰燼的利用價(jià)值趨于零
3.如果到現(xiàn)在還沒能說服你,那我想說,你很專業(yè)!即然這樣,那還有IE3,IE2,IE?FF1,NN4...,我想你應(yīng)該一并實(shí)現(xiàn)了。
一些坦白:我也不怎么說服得了我自已,唉,還是給一個(gè)IE5的解決方案吧:
IE5并不支持getElementByTagName("*")的形式,所以在這里要處理一下:
var elements = (tagName==='*'&&node.all)?node.all:node.getElementsByTagName(tagName);
好了,不多說的,這個(gè)函數(shù)簡單實(shí)用,代碼上我也寫了注釋,看明白應(yīng)該已經(jīng)沒有什么問題了
復(fù)制代碼 代碼如下:
/*
* 根據(jù)元素clsssName得到元素集合
* @param fatherId 父元素的ID,默認(rèn)為document
* @tagName 子元素的標(biāo)簽名
* @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++){
//創(chuàng)建匹配類名的正則
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)){//優(yōu)化循環(huán)
if(k === classNameLength){
result[result.length] = element;
break;
}
}
k = 0;
}
return result;
}
好,我們來測試一下:
復(fù)制代碼 代碼如下:
<div id="container">
<span class="aaa zzz ccc"></span>
<div class="aaa bbb ccc"></div>
</div>
<div class="aaa bbb ccc"></div>
復(fù)制代碼 代碼如下:
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
}
正確的得到了結(jié)果。
原生的getElementsByClassName
有人會(huì)問,原生的方法調(diào)用效率是最高的,有很多瀏覽器已經(jīng)將實(shí)現(xiàn)了getElementsByClassName這個(gè)方法,那為什這里沒有先調(diào)用原生的再調(diào)用自定義的呢?
對,原生的效率是很高,它支持多個(gè)class條件的查詢,但是最大的問題是他不支持getElementsByClassName("container","div","aaa ccc"),這種在指定標(biāo)簽中查找指定元素為指定class的情況。
所以,這里舍棄了原生的方法調(diào)用。
關(guān)于循環(huán)優(yōu)化的問題
在代碼中,你會(huì)看到我將數(shù)組的length緩存了起來,這樣可以提高效率。其實(shí)上,在這里有一個(gè)很隱蔽的問題,就是數(shù)組訪問length屬性和HtmlCollection訪問length有很在的區(qū)別。在數(shù)組中,length是一個(gè)普通的屬性,訪問時(shí)不會(huì)進(jìn)行額外的操作,在來看看HTMLCollection,我們常常將HTMLCollection當(dāng)作數(shù)組來使用,但實(shí)際上,它是一個(gè)根據(jù)DOM結(jié)構(gòu)自動(dòng)變化的實(shí)體對象。每次訪問一個(gè)HTMLCollection對象的屬性時(shí),他都會(huì)對DOM內(nèi)所有的節(jié)點(diǎn)進(jìn)行一次完整的匹配。也就是說,每次訪問HtmlCollection對象的length時(shí),都會(huì)更新一次集合對象,性能上消耗很大。所以一般情況之下,這種HtmlCollection的循環(huán)操作,都是建議緩存length的。
額外的收獲
這是關(guān)于往數(shù)組里放元素的方式間,效率比較的問題
來看一下代碼:
復(fù)制代碼 代碼如下:
//方式一
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;
}
猜猜看,哪種效率更高呢!經(jīng)過測試,第二種方式的效率要高于第一種。
提醒:
這個(gè)版本是不兼容IE5的,以下是我給出的解釋:
1.當(dāng)你從那千分之幾的統(tǒng)計(jì)數(shù)據(jù)里,再去瘋錢的IE5測試人員的點(diǎn)擊和專業(yè)程序員對IE5的好奇心,估計(jì)就只剩IE5被焚燒后的灰燼了。
2.你要想信灰燼的利用價(jià)值趨于零
3.如果到現(xiàn)在還沒能說服你,那我想說,你很專業(yè)!即然這樣,那還有IE3,IE2,IE?FF1,NN4...,我想你應(yīng)該一并實(shí)現(xiàn)了。
一些坦白:我也不怎么說服得了我自已,唉,還是給一個(gè)IE5的解決方案吧:
IE5并不支持getElementByTagName("*")的形式,所以在這里要處理一下:
var elements = (tagName==='*'&&node.all)?node.all:node.getElementsByTagName(tagName);
好了,不多說的,這個(gè)函數(shù)簡單實(shí)用,代碼上我也寫了注釋,看明白應(yīng)該已經(jīng)沒有什么問題了
您可能感興趣的文章:
- javascript getElementsByClassName函數(shù)
- js document.getElementsByClassName的使用介紹與自定義函數(shù)
- js 獲取class的元素的方法 以及創(chuàng)建方法getElementsByClassName
- javascript getElementsByClassName 和js取地址欄參數(shù)
- 使用classList來實(shí)現(xiàn)兩個(gè)按鈕樣式的切換方法
- Javascript 多瀏覽器兼容性問題及解決方案
- IE8的JavaScript點(diǎn)擊事件(onclick)不兼容的解決方法
- JavaScript在IE和Firefox(火狐)的不兼容問題解決方法小結(jié)
- JavaScript中解決多瀏覽器兼容性23個(gè)問題的快速解決方法
- JS中g(shù)etElementsByClassName與classList兼容性問題解決方案分析
相關(guān)文章
只需一行代碼,輕松實(shí)現(xiàn)一個(gè)在線編輯器
在瀏覽器地址欄中輸入一行代碼:data:text/html, <html contenteditable> ,回車即可把瀏覽器變臨時(shí)編輯器(需要瀏覽器支持 HTML5 屬性 contenteditable)2013-11-11
Bootstrap多級導(dǎo)航欄(級聯(lián)導(dǎo)航)的實(shí)現(xiàn)代碼
這篇文章主要介紹了Bootstrap多級導(dǎo)航欄的實(shí)現(xiàn)代碼的相關(guān)資料,需要的朋友可以參考下2016-03-03
Javascript實(shí)時(shí)柱狀圖實(shí)現(xiàn)代碼
js實(shí)現(xiàn)的實(shí)時(shí)柱狀圖,非常有創(chuàng)意的想法。2008-10-10
Javascript this 的一些學(xué)習(xí)總結(jié)
相信有C++、C#或Java等編程經(jīng)驗(yàn)的各位,對于this關(guān)鍵字再熟悉不過了。由于Javascript是一種面向?qū)ο蟮木幊陶Z言,它和C++、C#或Java一樣都包含this關(guān)鍵字,接下來我們將向大家介紹Javascript中的this關(guān)鍵字2012-08-08
JavaScript算法題之如何將一個(gè)數(shù)組旋轉(zhuǎn)k步
這篇文章主要給大家介紹了關(guān)于JavaScript算法題之如何將一個(gè)數(shù)組旋轉(zhuǎn)k步的相關(guān)資料,文中通過實(shí)例代碼介紹的非常詳細(xì),對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友可以參考下2022-03-03
JavaScript基于面向?qū)ο髮?shí)現(xiàn)的無縫滾動(dòng)輪播示例
這篇文章主要介紹了JavaScript基于面向?qū)ο髮?shí)現(xiàn)的無縫滾動(dòng)輪播,結(jié)合實(shí)例形式分析了JavaScript面向?qū)ο髮?shí)現(xiàn)的無縫滾動(dòng)輪播相關(guān)對象定義、初始化及功能實(shí)現(xiàn)技巧,需要的朋友可以參考下2020-01-01

