querySelector和querySelectorAll


jQuery被開發者如此的青睞和它強大的選擇器有很大關系,比起笨重的document.getElementById、document.getElementByName… ,查找元素很方便,其實W3C中提供了querySelector和querySelectorAll查詢接口已經實現了類似功能。

定義

其實這兩個方法看名字就能明白什么意思,不過還是引用一下W3C的解釋

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,這兩個方法使用很簡單,傳入選擇器即可

<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的實現有錯誤,看個例子

<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的父元素,所以應該返回空基赫才對,但是瀏覽器會返回

image

大神Andrew Dupont提出了一種方法修復這個bug,被廣泛應用到各個框架中,在selector前面指定調用元素的id,限制匹配范圍。在jQuery中大概是這么個意思

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了,直接使用這兩個方法吧


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM