`
lizaochengwen
  • 浏览: 663047 次
  • 性别: Icon_minigender_1
  • 来自: 北京
社区版块
存档分类
最新评论

querySelector 和 querySelectorAll 方法浏览器实现无误,避免将其与 JQuery 的选择器混淆

阅读更多
规范定义

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 class="warning">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 class="warning">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 class="warning">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 class="warning">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 class="warning">This is a sample warning</p>, <p >This is a sample error</p>,<p>...</p>];
    然后对比 <div id="foo"> 节点的子树中是否含有这些 p 元素。<div id="foo"> 节点的子树中仅含有[<p class="warning">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 class="warning">This is a sample warning</p>,<p >This is a sample error</p>]


这次的例子是在 <div id="foo"> 节点下寻找 html 标签中的body 标签中的 div 标签的直接子标签 P。

他的返回结果依然是 [<p class="warning">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 中选择器实现机理,它们是不同的。
测试环境
操作系统版本: Windows 7 Ultimate build 7600
浏览器版本: IE8
IE9
Firefox 4.0.1
Chrome 12.0.742.100
Safari 5.0.5
Opera 11.11
测试页面:
本文更新时间: 2011-09-26

分享到:
评论

相关推荐

    再谈querySelector和querySelectorAll的区别与联系

    例如,jQuery使用的方法是,在`baseElement`没有ID时,为其临时添加一个ID,然后在选择器中包含这个ID,确保搜索范围仅限于`baseElement`及其子元素。这种方法可以确保跨浏览器的一致性。 总的来说,`querySelector...

    javascript之querySelector和querySelectorAll使用介绍

    由于querySelector和querySelectorAll方法与jQuery选择器在语义上有相似之处,一些开发者可能会对这两个原生JavaScript方法的浏览器实现产生误解。例如,有些开发者可能会期待使用querySelectorAll返回的结果是可以...

    原生的强大DOM选择器querySelector.pdf

    querySelector和querySelectorAll是JavaScript DOM操作的重要工具,它们让开发者能够以CSS选择器的方式选取DOM元素,大大提高了代码的可读性和简洁性。理解这两个方法的用法和区别,对于编写高效、易维护的DOM操作...

    各浏览器中querySelector和querySelectorAll的实现差异分析

    querySelector和querySelectorAll是W3C提供的新的查询接口 querySelector和querySelectorAll是W3C提供的 新的查询接口,...这两个方法都可以接受三种类型的参数:id(#),class(.),标签,很像jquery的选择器。 var obj

    javascript高级选择器querySelector和querySelectorAll全面解析

    querySelector 和 querySelectorAll 方法是 W3C Selectors API 规范中定义的。他们的作用是根据 CSS 选择器规范,便捷定位文档中指定元素。 目前几乎主流浏览器均支持了他们。包括 IE8(含) 以上版本、 Firefox、 ...

    javascript之querySelector和querySelectorAll使用说明

    需要注意的是,虽然`querySelector`和`querySelectorAll`在大部分现代浏览器中都得到了支持,但在早期版本的Internet Explorer(如IE8)中,对CSS选择器的支持有限,仅限于CSS2.1的选择器。在不支持这些API的旧版...

    原生的强大DOM选择器querySelector介绍.docx

    W3C 的规范中对 querySelector 和 querySelectorAll 的实现进行了规定:querySelector 将返回匹配到的第一个元素,假如没有匹配的元素则返回 Null。querySelectorAll 返回一个包含匹配到的元素的数组,假如没有匹配...

    jQuery选择器querySelector的使用指南

    文档首先说明了HTML5的WebAPI引入了两个新的方法:document.querySelector和document.querySelectorAll,这两个方法的目的是为了更方便地从文档对象模型(DOM)中选取元素,其功能与jQuery的选择器相似。这样一来,...

    IE8下关于querySelectorAll()的问题

    在IE8中,querySelectorAll()方法的使用可能会遇到一些与其它浏览器不同的问题,尤其是在处理某些特定选择器时。querySelectorAll()方法是W3C标准的一部分,用于返回文档中匹配指定CSS选择器的所有元素。在IE8中,这...

    JS原生的强大DOM选择器querySelector.pdf

    `querySelector` 和 `querySelectorAll` 是JavaScript中用于DOM操作的两个强大方法,它们允许开发者使用CSS选择器的方式来选取DOM元素,极大地提高了代码的可读性和效率。这两个方法在现代浏览器中得到了广泛支持,...

    JQuery快速学一(强悍的选择器)

    虽然jQuery提供了一套强大的选择器系统,但需要注意的是,它也支持JavaScript原生的选择器API,如`querySelector()`和`querySelectorAll()`。这两个方法可以接受CSS选择器字符串,返回匹配的元素或元素集合。 总结...

    原生的强大DOM选择器querySelector介绍

    虽然querySelector和querySelectorAll的性能通常优于jQuery等库中的选择器方法,但它们在Internet Explorer 6和7中并不被支持。因此,在兼容性需求较高的项目中,可能需要额外的polyfill或使用其他库。 **W3C规范**...

    jQuery插件及其效率提高

    但部分浏览器的新版本通过增加querySelector和querySelectorAll方法,提升了这些选择器的性能。 #### 4. 选择器的正确使用 - 选择器的性能排序大致为:ID选择器 &gt; 标签选择器 &gt; Class选择器 &gt; 属性选择器和伪类选择...

    高效jQuery选择器的5个技巧实例分析

    本文实例讲述了高效jQuery选择器的5个技巧。分享给大家供大家参考,具体如下: 顾名思义,jQuery专注于查询(queries)。库的核心允许你使用CSS选择器语法,以及通过在集合上执行函数,来查找DOM元素。 jQuery使用...

Global site tag (gtag.js) - Google Analytics