原生的html元素選擇器類似jquery選擇器
做前端,需要選擇元素,雖說有jquery和各大js庫已經(jīng)幫我造好了輪子,但我想試試自己實(shí)現(xiàn)一個,正好項(xiàng)目也不忙,正好加入自己的js文件中,下面是實(shí)現(xiàn)代碼。用$g(“#content .op”)這種格式就可以調(diào)用,和jquery $()的參數(shù)一樣:
function $findChilds(parentNode, text)
{
//如果不傳入父節(jié)點(diǎn)的話,默認(rèn)為body
if(parentNode == undefined)
parentNode = document.body;
var childNodes = parentNode.childNodes;
var results = [];
//子節(jié)點(diǎn)大于零才循環(huán)
if(childNodes.length > 0)
{
var length = childNodes.length;
//循環(huán)查找符合text的節(jié)點(diǎn)
for(var i=0;i<length;++i)
{
//三種情況,className,id, tagName
switch(text.substr(0, 1))
{
case '.':
//這兩種:parentNode.getElementsByClassName,parentNode.all
//都是后來加上的,如果瀏覽器這兩種方法都不支持,那就只能暴力遞歸了
if(parentNode.getElementsByClassName)
return parentNode.getElementsByClassName(text.substr(1));
else if(parentNode.all)
{
var finded = [];
var jlength = parentNode.all.length;
for(var j=0;j<jlength;++j)
if(parentNode.all[j].className == text.substr(1))
finded.push(parentNode.all[j]);
return finded;
}
//以上兩種方法都不支持,直接判斷
if(childNodes[i].className == text.substr(1))
results.push(childNodes[i]);
break;
case '#':
return [document.getElementById(text.substr(1))];
default:
return parentNode.getElementsByTagName(text);
}
//判斷完后,把當(dāng)前子元素的子元素傳入$findChilds進(jìn)行遞歸查找,返回的結(jié)果直接和現(xiàn)在的結(jié)果合并
results = results.concat($findChilds(childNodes[i], text));
}
}
return results;
}
String.prototype.vtrim = function() {
return this.replace(/^\s+|\s+$/g, '');
}
function $g(text)
{
//按照空格分割參數(shù)
var values = text.vtrim().split(" ");
var length = values.length;
//如果只有一個選擇參數(shù)的話,就直接調(diào)用dom方法返回結(jié)果。
if(length == 1)
switch(values[0].substr(0, 1))
{
case "#":
return document.getElementById(values[0].substr(1));
case ".":
if(document.getElementsByClassName)
return document.getElementsByClassName(values[0].substr(1));
default:
return document.getElementsByTagName(values[0]);
}
//每次迭代都會產(chǎn)生許多符合參數(shù)的結(jié)果節(jié)點(diǎn),這里結(jié)果節(jié)點(diǎn)的名稱為parentNodes,第一次循環(huán)默認(rèn)為body
var parentNodes = [document.body];
//外層循環(huán)為迭代每個傳入的參數(shù)
for(var i = 0; i < length; ++i)
{
var jlength = parentNodes.length;
var results = [];
//這里如果values的長度為零的話,
//就說明是多出來的空格,
//例如:$g(" .content");這種情況不執(zhí)行代碼直接跳入下一循環(huán)
var tmpValue = values[i].vtrim();
if(tmpValue.length <= 0)
continue;
//內(nèi)層循環(huán)為迭代每個結(jié)果節(jié)點(diǎn),
//在結(jié)果節(jié)點(diǎn)中查找符合選擇條件的結(jié)果。當(dāng)然第一次為body
for(var j=0;j<jlength;++j)
{
//$findChilds就是上邊的那個函數(shù),就是選擇某個節(jié)點(diǎn)的子節(jié)點(diǎn)的
var result = $findChilds(parentNodes[j], values[i].vtrim());
var rlength = result.length;
//因?yàn)榉祷氐挠袝r候是html容器,無法直接和數(shù)組concat所以倒入數(shù)組,這里有優(yōu)化空間,但暫不考慮性能先這么做
for (var k = 0; k < rlength; ++k)
results.push(result[k]);
}
//沒有結(jié)果,立即返回undefined
if(results == undefined || results.length <= 0)
return undefined;
//最后一次循環(huán)就直接返回結(jié)果數(shù)組,但是如果最后一個選擇條件是選擇id的話,那就不返回數(shù)組直接返回dom對象了
if (i == length - 1)
{
if (values[i].substr(0, 1) == "#")
return results[0];
return results;
}
parentNodes = results;
}
}
經(jīng)過在ff ie6下的測試 單純的選擇id比jquery要快很多,
其他的部分選擇模式我測試的少數(shù)比jquery要快。
當(dāng)然測試不可能全面,還可能會有bug,而且不支持類似于.content:first-child這樣的偽類選擇。
相關(guān)文章
JavaScript中的普通函數(shù)與構(gòu)造函數(shù)比較
這篇文章主要介紹了JavaScript中的普通函數(shù)與構(gòu)造函數(shù)比較,需要的朋友可以參考下2015-04-04
JS+CSS實(shí)現(xiàn)高亮關(guān)鍵詞(不侵入DOM)的方式
這篇文章主要為大家詳細(xì)介紹了JS+CSS實(shí)現(xiàn)高亮關(guān)鍵詞(不侵入DOM)的方式,文中的示例代碼講解詳細(xì),具有一定的參考價值,感興趣的小伙伴可以跟隨小編一起學(xué)習(xí)一下2023-12-12
TypeScript中交叉類型和聯(lián)合類型的區(qū)別詳解
聯(lián)合類型(Union Types)和交叉類型(Intersection Types)是 TypeScript 中的兩種高級類型,它們都用于組合多個類型并生成新的類型,但它們兩者之間的用法不一樣,本文小編就給大家講講TypeScript中交叉類型和聯(lián)合類型的區(qū)別,需要的朋友可以參考下2023-09-09
Javascript級聯(lián)下拉菜單以及AJAX數(shù)據(jù)驗(yàn)證核心代碼
最初是只要輸入框的兩個數(shù)據(jù)相符就行,現(xiàn)在的要求是兩個下拉菜單的數(shù)據(jù)也要相符,于是,我利用此機(jī)會,將代碼重構(gòu)了一次,感興趣的朋友們可以借此學(xué)習(xí)一下2013-05-05
原生Js頁面滾動延遲加載圖片實(shí)現(xiàn)原理及過程
頁面滾動加載事件,獲取元素在頁面里的top值根據(jù)滾動條的位置判斷何時顯示圖片;獲取元素集合 加載過的圖片從集合里刪除,具體實(shí)現(xiàn)如下,感興趣的朋友各位可以參考下哈2013-06-06

