querySelector和querySelectorAll是W3C提供的 新的查詢接口。
目前幾乎主流瀏覽器均支持了他們,包括 IE8(含) 以上版本、 Firefox、 Chrome、Safari、Opera。
萬能的sizzle在高版本的瀏覽器中復雜的選擇器盡量走querySelectorAll,前提是這個匹配的節點沒有兼容問題。
從IE8開始雖然支持querySelectorAll的API,但是會有各式各樣的BUG,所以sizzle拿rbuggyQSA用來記錄這個BUG問題。
if ( support.qsa && (!rbuggyQSA || !rbuggyQSA.test( selector )) ) { //newContext.querySelectorAll( newSelector ) }
zepto的選擇器則更直接:
zepto.qsa = function(element, selector) { return element.querySelectorAll(selector) }
jQuery的選擇器當然都是優先選擇querySelectorAll,否則的話就走sizzle的邏輯,當然IE6 7是必須的,IE8雖然實現了querySelectorAll,但是也有一些問題,具體我們后面分析。
關于querySelectorAll接口定義:
partial interface Document { Element? querySelector(DOMString selectors); NodeList querySelectorAll(DOMString selectors); }; partial interface DocumentFragment { Element? querySelector(DOMString selectors); NodeList querySelectorAll(DOMString selectors); }; partial interface Element { Element? querySelector(DOMString selectors); NodeList querySelectorAll(DOMString selectors); };
從接口定義可以看到Document、DocumentFragment、Element都實現了NodeSelector接口。即這三種類型的元素都擁有者兩個方法。
querySelector和querySelectorAll的參數須是符合 css selector 的字符串。
不同的是querySelector返回的是一個對象,querySelectorAll返回的一個集合(NodeList)。
所以選擇querySelectorAll更符合jQuery這個合集對象的習慣。
document.querySelectorAll 與 element.querySelectorAll區別?
當調用上下文是document的時候,沒有什么問題,各瀏覽器的實現基本一致,如果調用的上下文是element,dom Node的時候,瀏覽器的實現有點不同。
具體就是表現在:
element.querySelectorAll 在文檔內找全部符合選擇器描述的節點包括Element本身
對照一組代碼:
//通過一個上下文查找 var aaRoot = document.getElementById('aaronId'); var element = aaRoot.querySelector('.aaron span'); //直接查找 var elementList = document.querySelectorAll('.aaron span');
問題出在aaRoot.querySelector盡然還有返回值!因為上下文查找的范圍包含了自身了。
選擇上下文是在aaRoot里面,選擇器是.aaron就父節點,理論是找不到對應的節點的。
所以邏輯上是不合理的,因為根本找不到,但是結果跟document調用如出一轍,所以此時node ele類似document了。
可能的查找機制是這樣的:
首先在document的范圍內進行查找所有滿足選擇器條件的元素, 在上面這段代碼中,我們的選擇器是.aaron span,就是所有的直接父元素類名為aaron的元素。 然后,再看哪些元素是調用querySelector/querySelectorAll的元素的子元素,這些元素將會被返回。 這也就說明了為什么element會一同返回。
請驗證,完成請求
由于請求次數過多,請先驗證,完成再次請求
打開微信掃碼自動綁定
綁定后可得到
使用 Ctrl+D 可將課程添加到書簽
舉報