querySelector 和 querySelectorAll
規范定義
querySelector 和 querySelectorAll 方法是?W3C Selectors API Level 1?規范中定義的。他們的作用是根據 CSS 選擇器規范,便捷定位文檔中指定元素。
目前幾乎主流瀏覽器均支持了他們。包括 IE8(含) 以上版本、 Firefox、 Chrome、Safari、Opera。
querySelector 和 querySelectorAll 在規范中定義了如下接口:
module dom {
[Supplemental, NoInterfaceObject]
interface NodeSelector {
Element querySelector(in DOMString selectors);
NodeList querySelectorAll(in DOMString selectors);
};
Document implements NodeSelector;
DocumentFragment implements NodeSelector;
Element implements NodeSelector;
};
其實就是任何 NodeList 、Element 的實例對象和 Document DocumentFragment 的實例對象都有這兩個方法。如:
- document.querySelectorAll
- document.querySelector
- nodeList.querySelectorAll
- nodeList.querySelector
- element.querySelectorAll
- element.querySelector
querySelectorAll 返回符合 Selector 條件的所有節點內容,是個 NodeList;querySelector 僅返回符合 Selector 條件的第一個節點內容,是個 Node。
如何用 querySelectorAll 或 querySelector呢?來看個例子:
HTML CODE:
<DOCTYPE html>
<html>
<head>
<title>Selectors API Example</title>
</head>
<body>
<div id="foo">
<p>This is a sample warning</p>
<p >This is a sample error</p>
</div>
<div id="bar">
<p>...</p>
</div>
</body>
</html>
JAVASCRIPT CODE:
var alerts = document.querySelectorAll("p.warning, p.error");
// 返回 [<p>This is a sample warning</p>,<p>This is a sample error</p>]
哈哈,是不是很好用啊。
JQuery 的 Selector
那我們怎么兼容低版本的瀏覽器呢?不用著急,有 JQuery 呢,這個火爆的東東早早就實現了 Selectors。
JAVASCRIPT JQuery CODE:
var alerts = $("p.warning, p.error");
// 返回 [<p>This is a sample warning</p>,<p >This is a sample error</p>]
這與使用 和querySelectorAll 結果一致。
兩者間差異
再用用 element.querySelectorAll 看看:
JAVASCRIPT CODE:
var foo= document.getElementById("foo");
foo.querySelectorAll("div > p");
// 返回 [<p>This is a sample warning</p>,<p >This is a sample error</p>]
JAVASCRIPT JQuery CODE:
var foo= document.getElementById("foo");
$(foo).find("div > p")
// 返回 []
玩砸了……為什么兩者返回結果不一致了呢?
我們看下傳入的選擇器字符串含義,不就是在 <div id="foo"> 節點下尋找 div 標簽下的 p 標簽么?
<div id="foo"> 節點下沒有 div 標簽了,當然應該返回一個空 nodeList。JQuery 返回的結果是正確的。很奇怪,難道說所有實現了 querySelector和 querySelectorAll 方法的瀏覽器都沒遵守規范?這也太坑爹了!!
等等,我們還是先看看規范定義怎么說:
querySelectorAll : when invoked, return a NodeList containing all of the matching Element nodes within the node’s subtrees, in document order. 還有一句 :Even though the method is invoked on an element, selectors are still evaluated in the context of the entire document.
結合起來看,規范定義為選擇器在以整個文檔為基準,查找全部符合選擇器描述的節點,判斷返回的 NodeList 是否在 Element 子樹內,如果是在 Element 子樹內,則這些節點組成 NodeList 返回,其排序需與文檔原始節點排序一致。
根據這個定義,我們看瀏覽器實現:
- 先是在文檔中找到所有處于 div 標簽內的 p 子節點,他們是 [<p>This is a sample warning</p>, <p >This is a sample error</p>,<p>...</p>];
- 然后對比 <div id="foo"> 節點的子樹中是否含有這些 p 元素。<div id="foo"> 節點的子樹中僅含有[<p>This is a sample warning</p>, <p >This is a sample error</p>],那么就返回他們吧。這與之前問題例子返回結果一致。
這么說,瀏覽器實現沒錯?好吧,我們可以再做個更離譜的測試來看看:
JAVASCRIPT CODE:
var foo= document.getElementById("foo");
foo.querySelectorAll("html body div > p");
// 返回 [<p>This is a sample warning</p>,<p >This is a sample error</p>]
這次的例子是在 <div id="foo"> 節點下尋找 html 標簽中的body 標簽中的 div 標簽的直接子標簽 P。
他的返回結果依然是 [<p>This is a sample warning</p>,<p >This is a sample error</p>]
這與規范說明一致。
這么說,瀏覽器本身實現并沒有問題,而是JQuery有問題了?其實這也并不盡然,JQuery 本身并沒有宣布遵守 W3C Selectors API Level 1 規范實現查找結果,他的選擇器 API 實現是私有的。
對于 Element 下的選擇器范圍,JQuery 認為是從當前元素開始查找,返回符合的結果集。而規范恰恰指出的是選擇器只針對當前文檔,選擇出的結果集再與當前元素的子樹比較。
正是由于以上的不同導致了他們返回結果不一致。
建議
切記不要在實際使用中混淆 W3C Selectors API Level 1 規范中選擇器的實現機理和 JQuery 中選擇器實現機理,它們是不同的。
總結
以上是生活随笔為你收集整理的querySelector 和 querySelectorAll的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 关于时间的名言警句大全集165个
- 下一篇: 让女朋友感动到哭的话 女孩子听了最心动的