querySelector和querySelectorAll

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]');

image

缺陷及解決辦法

確實很好用,可是瀏覽器對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

image

大神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,獲得正確結果接口

image

瀏覽器兼容性

雖然有些問題,但瑕不掩瑜,這麼好用的兩個方法咋沒火呢?瀏覽器兼容性。。。其實比起一些HTML5和CSS3的特性來講這兩個方法還沒那麼讓人絕望,由於IE8都已經支持了,其它各個主力主流瀏覽器天然是實現了。

IE8+

Firefox

Chrome

Safari

Opera

Android

因此騷年們若是你是針對Mobile web優化,不要引用jQuery了,直接使用這兩個方法吧

相關文章
相關標籤/搜索