jQuery原理系列-css選擇器的簡(jiǎn)單實(shí)現(xiàn)
jQuery最強(qiáng)大的功能在于它可以通過(guò)css選擇器查找元素,它的源碼中有一半是sizzle css選擇器引擎的代碼,在html5規(guī)范出來(lái)之后,增加了document.querySelector和document.querySelectorAll直接查找元素,如果是做移動(dòng)端開發(fā)的,使用jQuery的必要性大大降低。
用js代碼實(shí)現(xiàn)css選擇器,必然是用正則表達(dá)式來(lái)識(shí)別字符串了,當(dāng)然瀏覽器提供的原生api 效率更高,以下代碼只做原理性展示,并未優(yōu)先性能,
例如
1)查找id顯然是用document.getElementById更高效,瀏覽器已經(jīng)做了hash,一次性找到元素不用遍歷每個(gè)節(jié)點(diǎn)。
2)查找 name用document.getElementsByName更高效,瀏覽器已經(jīng)做了一個(gè)含有該name的集合,
3)查找標(biāo)簽名 用document.getElementsByTagName更高效,瀏覽器已經(jīng)做了一個(gè)含有該tag集合,從這個(gè)集合中再查找子集顯然可以少遍歷很多的元素,至于瀏覽器是不是在元素創(chuàng)建的時(shí)候就更新了緩存的集合就不得而知了,但是從這個(gè)集合中判斷是不是目標(biāo)元素的子節(jié)點(diǎn)還要用contains也會(huì)有性能損耗。
好了,我們先不考慮用原生api優(yōu)化選擇器的問(wèn)題,只用純正則表達(dá)式來(lái)做一個(gè)簡(jiǎn)單的實(shí)現(xiàn),先用正則判斷如果含有#就是id選擇器,如果含有點(diǎn)號(hào)就是class選擇器,如果含有[]就是屬性選擇器,設(shè)定好查找目標(biāo)后開始遍歷子節(jié)點(diǎn),要用遞歸函數(shù)遍歷childNodes子節(jié)點(diǎn)的id,name,className,getAttribute是否匹配,如果匹配就返回該元素。完整的代碼如下:
html:
<body>
<div>
<span id="sp_id">hello,id</span>
<span class="sp_class">hello,class</span>
<span name="sp_name" >hello,name</span>
<b>hello,tag</b>
</div>
</body>
javascript:
<script type="text/javascript">
function find(el, selector) { //查找子節(jié)點(diǎn),用法類似jquery的find函數(shù),僅支持id,class,attr選擇器,僅支持返回匹配的第一個(gè)元素
var m = selector.match(/([#\.\[])([\w\W]+)/i);
var type, key,attrName, result;
if (m) {
if (m[1] == ".") {
type = "class"; key = m[2];
} else if (m[1] == "#") {
type = "id"; key = m[2];
} if (m[1] == "[") {
type = "attr";
m = m[2].match(/(\w+)=(\w+)/i);
attrName = m[1];
key = m[2];
}
} else {
type = "tag"; key = selector;
}
function findChild(node) {
var c;
for (var i = 0; i < node.childNodes.length; i++) {
c = node.childNodes[i];
if (type == "class" && c.className == key) {
result = c;
return;
} else if (type == "id" && c.id == key) {
result = c;
return;
} else if (type == "attr" && c.getAttribute && c.getAttribute(attrName) == key) {
result = c;
return;
} else if (type == "tag" && c.tagName && c.tagName.toLowerCase() == key) {
result = c;
return;
}
findChild(c);
}
}
findChild(el);
return result;
}
console.log(find(document.body,"#sp_id").innerHTML);
console.log(find(document.body,".sp_class").innerHTML);
console.log(find(document.body,"[name=sp_name]").innerHTML);
console.log(find(document.body,"b").innerHTML);
</script>
以上這篇jQuery原理系列-css選擇器的簡(jiǎn)單實(shí)現(xiàn)就是小編分享給大家的全部?jī)?nèi)容了,希望能給大家一個(gè)參考,也希望大家多多支持腳本之家。
相關(guān)文章
jQuery實(shí)現(xiàn)下拉框功能實(shí)例代碼
這篇文章主要介紹了jQuery實(shí)現(xiàn)下拉框功能實(shí)例代碼的相關(guān)資料,需要的朋友可以參考下2016-05-05
淺析onsubmit校驗(yàn)表單時(shí)利用ajax的return false無(wú)效問(wèn)題
前幾天,在校驗(yàn)一個(gè)表單數(shù)據(jù)用到ajax時(shí),遇到 return false 無(wú)效問(wèn)題,以下就是對(duì)這個(gè)問(wèn)題進(jìn)行了分析介紹,需要的朋友可以參考下2013-07-07
JS實(shí)現(xiàn)點(diǎn)擊生成UUID的方法完整實(shí)例【基于jQuery】
這篇文章主要介紹了JS實(shí)現(xiàn)點(diǎn)擊生成UUID的方法,結(jié)合完整實(shí)例形式分析了基于jQuery實(shí)現(xiàn)的隨機(jī)字符串生成相關(guān)操作技巧,需要的朋友可以參考下2019-06-06
jQuery實(shí)現(xiàn)Meizu魅族官方網(wǎng)站的導(dǎo)航菜單效果
這篇文章主要介紹了jQuery實(shí)現(xiàn)Meizu魅族官方網(wǎng)站的導(dǎo)航菜單效果,可實(shí)現(xiàn)導(dǎo)航菜單項(xiàng)鼠標(biāo)滑過(guò)出現(xiàn)下劃線動(dòng)態(tài)跟隨的功能,通過(guò)jQuery插件實(shí)現(xiàn)該功能,需要的朋友可以參考下2015-09-09
jQuery實(shí)現(xiàn)點(diǎn)擊任意位置彈出層外關(guān)閉彈出層效果
在之前做項(xiàng)目的時(shí)候經(jīng)常會(huì)在主頁(yè)面上點(diǎn)擊某個(gè)按鈕,右側(cè)彈出一個(gè)div輸出對(duì)應(yīng)內(nèi)容的詳細(xì)信息,怎么實(shí)現(xiàn)的呢,今天小編給大家分享通過(guò)jquery實(shí)現(xiàn)點(diǎn)擊任意位置彈出層外關(guān)閉彈出層效果,感興趣的朋友一起看看吧2016-10-10
jquery實(shí)現(xiàn)marquee效果(文字或者圖片的水平垂直滾動(dòng))
原本在前端html代碼中,實(shí)現(xiàn)文字或者圖片的水平垂直滾動(dòng),都是使用的marquee,但隨著考慮瀏覽器的兼容性和符合為w3c的標(biāo)準(zhǔn),接下來(lái)介紹使用Jquery實(shí)現(xiàn)網(wǎng)頁(yè)marquee效果,感興趣的朋友可以了解下哦2013-01-01

