国产探花免费观看_亚洲丰满少妇自慰呻吟_97日韩有码在线_资源在线日韩欧美_一区二区精品毛片,辰东完美世界有声小说,欢乐颂第一季,yy玄幻小说排行榜完本

首頁 > 編程 > JavaScript > 正文

javascript getElementsByClassName實現(xiàn)代碼

2019-11-21 00:12:39
字體:
來源:轉載
供稿:網(wǎng)友
先來看一下代碼:(支持多個class查詢和在某個范圍內進行查詢)
復制代碼 代碼如下:

/*
* 根據(jù)元素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++){
//創(chuàng)建匹配類名的正則
className[i]= new RegExp("(^|//s)" + className[i].replace(//-/g, "http://-") + "(//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
}

正確的得到了結果。
原生的getElementsByClassName
有人會問,原生的方法調用效率是最高的,有很多瀏覽器已經(jīng)將實現(xiàn)了getElementsByClassName這個方法,那為什這里沒有先調用原生的再調用自定義的呢?
對,原生的效率是很高,它支持多個class條件的查詢,但是最大的問題是他不支持getElementsByClassName("container","div","aaa ccc"),這種在指定標簽中查找指定元素為指定class的情況。
所以,這里舍棄了原生的方法調用。
關于循環(huán)優(yōu)化的問題
在代碼中,你會看到我將數(shù)組的length緩存了起來,這樣可以提高效率。其實上,在這里有一個很隱蔽的問題,就是數(shù)組訪問length屬性和HtmlCollection訪問length有很在的區(qū)別。在數(shù)組中,length是一個普通的屬性,訪問時不會進行額外的操作,在來看看HTMLCollection,我們常常將HTMLCollection當作數(shù)組來使用,但實際上,它是一個根據(jù)DOM結構自動變化的實體對象。每次訪問一個HTMLCollection對象的屬性時,他都會對DOM內所有的節(jié)點進行一次完整的匹配。也就是說,每次訪問HtmlCollection對象的length時,都會更新一次集合對象,性能上消耗很大。所以一般情況之下,這種HtmlCollection的循環(huán)操作,都是建議緩存length的。
額外的收獲
這是關于往數(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)過測試,第二種方式的效率要高于第一種。
提醒:
這個版本是不兼容IE5的,以下是我給出的解釋:
1.當你從那千分之幾的統(tǒng)計數(shù)據(jù)里,再去瘋錢的IE5測試人員的點擊和專業(yè)程序員對IE5的好奇心,估計就只剩IE5被焚燒后的灰燼了。
2.你要想信灰燼的利用價值趨于零
3.如果到現(xiàn)在還沒能說服你,那我想說,你很專業(yè)!即然這樣,那還有IE3,IE2,IE?FF1,NN4...,我想你應該一并實現(xiàn)了。
一些坦白:我也不怎么說服得了我自已,唉,還是給一個IE5的解決方案吧:
IE5并不支持getElementByTagName("*")的形式,所以在這里要處理一下:
var elements = (tagName==='*'&&node.all)?node.all:node.getElementsByTagName(tagName);
好了,不多說的,這個函數(shù)簡單實用,代碼上我也寫了注釋,看明白應該已經(jīng)沒有什么問題了
發(fā)表評論 共有條評論
用戶名: 密碼:
驗證碼: 匿名發(fā)表
主站蜘蛛池模板: 正宁县| 金昌市| 乌兰察布市| 江城| 西宁市| 邢台县| 虹口区| 广南县| 伊宁市| 固安县| 乌兰浩特市| 唐河县| 太和县| 南靖县| 含山县| 德令哈市| 九龙县| 南岸区| 莲花县| 武功县| 陈巴尔虎旗| 安吉县| 黄陵县| 睢宁县| 麟游县| 鄯善县| 驻马店市| 普安县| 康马县| 湄潭县| 沈丘县| 江山市| 福贡县| 安远县| 那曲县| 阿合奇县| 游戏| 巴彦淖尔市| 石台县| 新余市| 通州区|