jQuery被開發者如此的青睞和它強大的選擇器有很大關係,比起笨重的document.getElementById、document.getElementByName… ,查找元素很方便,其實W3C中提供了querySelector和querySelectorAll查詢接口已經實現了相似功能。node
其實這兩個方法看名字就能明白什麼意思,不過仍是引用一下W3C的解釋web
querySelector:return the first matching Element node within the node’s subtrees. If there is no such node, the method must return null .(返回指定元素節點的子樹中匹配選擇器的集合中的第一個元素,若是沒有匹配返回null)瀏覽器
querySelectorAll:return a NodeList containing all of the matching Element nodes within the node’s subtrees, in document order. If there are no such nodes, the method must return an empty NodeList. (按文檔順序返回指定元素節點的子樹中匹配選擇器的元素集合,若是沒有匹配返回空集合)框架
從定義能夠看到Document和Element都實現了NodeSelector接口。即這三種類型的元素都擁有者兩個方法。querySelector和querySelectorAll的參數是CSS選擇器字符串。區別在於querySelector返回的是一個第一個匹配元素,querySelectorAll返回的一個全部匹配元素集合(NodeList)。優化
若是使用過jQuery或者瞭解CSS,這兩個方法使用很簡單,傳入選擇器便可spa
<div id="test"> <div class="dialog"> <p> 123</p> <span>456</span> <div> 789</div> <div class="text"> 452</div> </div> </div>
var test=document.querySelector('#test'); var subDivs = test.querySelectorAll('div'); var text = document.querySelectorAll('div[class=text]');
確實很好用,可是瀏覽器對Element.querySelector和Element.querySelectorAll的實現有錯誤,看個例子3d
<div id="test"> <p> <span>123</span> </p> </div>
var test=document.querySelector('#test'); var span = test.querySelectorAll('div span');
按照咱們的理解span因該是搜索test內部祖先元素爲div的span元素,可是其祖先必須在test內部,而不能包括test自己甚至test的父元素,因此應該返回空基赫纔對,可是瀏覽器會返回code
大神Andrew Dupont提出了一種方法修復這個bug,被普遍應用到各個框架中,在selector前面指定調用元素的id,限制匹配範圍。在jQuery中大概是這麼個意思blog
var span, selector = 'div span',context=document.querySelector('#test'); var oldContext = context, oldId = context.getAttribute('id'), newId = oldId || '__sizzle__'; try { span= context.querySelectorAll('#'+newId+' '+selector); } catch (e) { } finally { if (!oldId) { oldContext.removeAttribute('id'); } }
這樣作實際上是給搜索加了一層id的限制,巧妙的利用了這個bug,獲得正確結果接口
雖然有些問題,但瑕不掩瑜,這麼好用的兩個方法咋沒火呢?瀏覽器兼容性。。。其實比起一些HTML5和CSS3的特性來講這兩個方法還沒那麼讓人絕望,由於IE8都已經支持了,其它各個主力主流瀏覽器天然是實現了。
IE8+
Firefox
Chrome
Safari
Opera
Android
因此騷年們若是你是針對Mobile web優化,不要引用jQuery了,直接使用這兩個方法吧