日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當(dāng)前位置: 首頁 > 编程资源 > 综合教程 >内容正文

综合教程

我的getElementsByClassName实现

發(fā)布時間:2024/8/24 综合教程 31 生活家
生活随笔 收集整理的這篇文章主要介紹了 我的getElementsByClassName实现 小編覺得挺不錯的,現(xiàn)在分享給大家,幫大家做個參考.

先來看一下代碼:(支持多個class查詢和在某個范圍內(nèi)進(jìn)行查詢)

/*
 * 根據(jù)元素clsssName得到元素集合
 * @param fatherId 父元素的ID,默認(rèn)為document
 * @tagName 子元素的標(biāo)簽名
 * @className 用空格分開的className字符串
 */
function getElementsByClassName(fatherId,tagName,className){
	var 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é)果。

關(guān)于class屬性

1.一個元素可以帶有多個class屬性值,它們通過空格分隔, 例:class='aa bb cc'。

2.class屬性值是可以包含'-'這個字符的,如:class='a-b',特別強(qiáng)調(diào)是因為在正則表達(dá)式中'-'是一個特殊字符。

3.在javascript中通過的獲取class屬性值的方式為element.className。

原生的getElementsByClassName

有人會問,原生的方法調(diào)用效率是最高的,有很多瀏覽器已經(jīng)將實現(xiàn)了getElementsByClassName這個方法,那為什這里沒有先調(diào)用原生的再調(diào)用自定義的呢?

對,原生的效率是很高,它支持多個class條件的查詢,但是最大的問題是他不支持getElementsByClassName("container","div","aaa ccc"),這種在指定標(biāo)簽中查找指定元素為指定class的情況。

所以,這里舍棄了原生的方法調(diào)用。

關(guān)于循環(huán)優(yōu)化的問題

在代碼中,你會看到我將數(shù)組的length緩存了起來,這樣可以提高效率。其實上,在這里有一個很隱蔽的問題,就是數(shù)組訪問length屬性和HtmlCollection訪問length有很在的區(qū)別。在數(shù)組中,length是一個普通的屬性,訪問時不會進(jìn)行額外的操作,在來看看HTMLCollection,我們常常將HTMLCollection當(dāng)作數(shù)組來使用,但實際上,它是一個根據(jù)DOM結(jié)構(gòu)自動變化的實體對象。每次訪問一個HTMLCollection對象的屬性時,他都會對DOM內(nèi)所有的節(jié)點進(jìn)行一次完整的匹配。也就是說,每次訪問HtmlCollection對象的length時,都會更新一次集合對象,性能上消耗很大。所以一般情況之下,這種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)過測試,第二種方式的效率要高于第一種。

提醒:

這個版本是不兼容IE5的,以下是我給出的解釋:

1.當(dāng)你從那千分之幾的統(tǒng)計數(shù)據(jù)里,再去瘋錢的IE5測試人員的點擊和專業(yè)程序員對IE5的好奇心,估計就只剩IE5被焚燒后的灰燼了。

2.你要想信灰燼的利用價值趨于零

3.如果到現(xiàn)在還沒能說服你,那我想說,你很專業(yè)!即然這樣,那還有IE3,IE2,IE?FF1,NN4...,我想你應(yīng)該一并實現(xiàn)了。

一些坦白:我也不怎么說服得了我自已,唉,還是給一個IE5的解決方案吧:

IE5并不支持getElementByTagName("*")的形式,所以在這里要處理一下:

var elements = (tagName==='*'&&node.all)?node.all:node.getElementsByTagName(tagName);

好了,不多說的,這個函數(shù)簡單實用,代碼上我也寫了注釋,看明白應(yīng)該已經(jīng)沒有什么問題了

總結(jié)

以上是生活随笔為你收集整理的我的getElementsByClassName实现的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網(wǎng)站內(nèi)容還不錯,歡迎將生活随笔推薦給好友。