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了,直接使用这两个方法吧



    本文转自魏琼东博客园博客,原文链接:http://www.cnblogs.com/dolphinX/p/3354318.html ,如需转载请自行联系原作者
相关文章
|
9月前
innerHTML和innerText的使用
innerHTML和innerText的使用
26 0
scrollTop详测
scrollTop详测
106 0
|
前端开发
你知道offsetHeight、scrollHeight、clientHeight的区别吗?
前言 offsetHeight、scrollHeight、clientHeight这三个属性我们经常在开发中遇到,如果小伙伴们没有经常使用的话,很容易把这些属性搞混,比如说什么窗口高度、元素高度、内容高度等等。当然,现在的前端框架很多时候帮我们封装了这些属性,但是我们也不能太过依赖框架,底层的原理我们还是需要了解的,今天就来理一理这三个属性分别代表什么?
150 0
你知道offsetHeight、scrollHeight、clientHeight的区别吗?
|
Web App开发 JavaScript iOS开发
|
JavaScript 前端开发
|
API 编解码
clientHeight、offsetHeight、scrollHeight详解
  网页可见区域宽: document.body.clientWidth; 网页可见区域高: document.body.clientHeight; 网页可见区域宽: document.body.offsetWidth   (包括边线的宽); 网页可见区域高: document.
1434 0
|
Web App开发 JavaScript 索引