天天看點

sizzle分析記錄:關于querySelectorAll相容問題

目前幾乎主流浏覽器均支援了他們。包括 IE8(含) 以上版本、 Firefox、 Chrome、Safari、Opera。

萬能的sizzle在高版本的浏覽器中複雜的選擇器盡量走querySelectorAll,前提是這個比對的節點沒有相容問題

從IE8開始雖然支援querySelectorAll的API,但是會有各式各樣的BUG,是以sizzle拿rbuggyQSA用來記錄這個BUG問題

zepto的選擇器則更直接

<a></a>

sizzle 2000行,zepto直接querySelectorAll接口,利弊各自評估了

重點就看querySelectorAll的坑到底有哪些?

接口定義:

從接口定義可以看到Document、DocumentFragment、Element都實作了NodeSelector接口。即這三種類型的元素都擁有者兩個方法。

不同的是querySelector傳回的是一個對象,querySelectorAll傳回的一個集合(NodeList)。

是以選擇querySelectorAll更符合jQuery這個合集對象的習慣

js

問題出在testElement.querySelector盡然還有傳回值!選擇上下文是在aaElement裡面,選擇器是.aaarn就父節點,理論是找不到對應的節點的

是以邏輯上是不合理的,因為根本找不到,但是結果跟document調用如出一轍,是以此時node ele類似document 了

可能的查找機制是這樣的:首先在document的範圍内進行查找所有滿足選擇器條件的元素,

在上面這段代碼中,我們的選擇器是.aaron span,就是所有的直接父元素類名為aaron的元素。

然後,再看哪些元素是調用querySelector/querySelectorAll的元素的子元素,這些元素将會被傳回

這也就說明了為什麼aaElement會一同傳回

那麼針對這種情況如何相容?

程式員的智慧總是無窮的, Andrew Dupont提出了一個解決方案,來自jQuery2.1.1

先看看jQuery最終的實作newContext.querySelectorAll用的上下文調用

代碼可見newContext可能是document || 提供的一個上下文

如:("#aaronId").find("div[class='text']) 此時的上下文即是("#aaronId").find("div[class='text']) 此時的上下文即是("#aaronId")節點

jQuery(element).find(selector) 在文檔内找全部符合選擇器描述的節點不包括Element本身

注意finally總是執行context.removeAttribute("id"),意味着我們在之前的處理強制加了一個id

反推hack的手法,selectors前面指定上下文的的id,限制比對的範圍

版本各有實作的不同,但是我們目前最終版為标準2.1.1

IE 8 :不支援上下文為object;

1. 關鍵是給context設定一個id

是以上下文content,就會存在這個id限制範圍

sizzle分析記錄:關于querySelectorAll相容問題

2. 拼接出查詢的選擇器,附上這個ID字首

3. 查詢

4. 因為強制加了ID,是以需要删除

這樣就達到目的範圍限制:context.querySelectorAll了

querySelectorAll在選擇器上存在的問題,具體我是看jQuery的源碼相關處理,基本都是IE8上的問題

jQuery對相容的判斷,都是采用的功能判斷直接特性檢測,僞造一個真實的環境測試支援度

針對querySelectorAll選取存在的問題之後分析

本文轉自艾倫 Aaron部落格園部落格,原文連結:http://www.cnblogs.com/aaronjs/p/3847964.html,如需轉載請自行聯系原作者

繼續閱讀