querySelectorAll 与jquery.find 与htmlcollection 的区别

querySelector 和 querySelectorAll

规范定义

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。

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 认为是从当前元素开始查找,返回符合的结果集。而规范恰恰指出的是选择器只针对当前文档,选择出的结果集再与当前元素的子树比较。

正是由于以上的不同导致了他们返回结果不一致。

NodeList 和 HTMLCollection之间的关系?

历史上的DOM集合接口。主要不同在于HTMLCollection是元素集合而NodeList是节点集合(即可以包含元素,也可以包含文本节点)。所以 node.childNodes 返回 NodeList,而 node.children 和 node.getElementsByXXX 返回 HTMLCollection 。

唯一要注意的是 querySelectorAll 返回的虽然是 NodeList ,但是实际上是元素集合,并且是静态的(其他接口返回的HTMLCollection和NodeList都是live的)。事实上,将来浏览器将增加 queryAll 接口取代现在的 querySelectorAll,返回 Elements 是 Array 的子类(因而可以使用Array上的forEach、map等方法)。

历史上dom1、dom2乃至dom3标准都是分core/XML和HTML部分的。getElementsByTagName是在core里的(即XML也有的),所以不可能返回HTMLCollection。但是现在的dom标准已经不分core和html了,反映的是浏览器的实现。
NodeList跟HTMLCollection有个差异是前者没有namedItem()方法后者是有的

时间: 2024-12-17 03:47:30

querySelectorAll 与jquery.find 与htmlcollection 的区别的相关文章

jQuery - 01. jQuery特点、如何使用jQuery、jQuery入口函数、jQuery和DOM对象的区别、jQuery选择器、

this指的是原生js的DOM对象 .css(""):只写一个值是取值,写俩值是赋值 window.onload   ===   $(document).ready(); $(""):获取元素   标签名..类名.#id jQuery特点 链式编程 jq.shou(3000).html(内容) 相当于 jq.shou(3000) jq.gtml(内容) 隐式迭代 隐式实用for循环.迭代 如何使用jQuery 引包 一定要在使用之前 <script src =

jquery之empty()与remove()区别

jquery之empty()与remove()区别 要用到移除指定元素的时候,发现empty()与remove([expr])都可以用来实现.可仔细观察效果的话就可以发现.empty()是只移除了 指定元素中的所有子节点,拿$("p").empty()来说,他只是把<p>dsfsd</p>中的文本给移除了,而留下 了<p></p>,仍保留其在dom中所占的位置.remove([expr])则是把其从dom中删除,而不会保留其所占的位置.例

javascript 与 jquery 中的函数调用的区别

标签:例如<input id="btn_show" type="button" onclick="show()" /> <script type="text/javascript"> $(function(){ function show(){ -- } }) function show(){ -- } </script> 注意, 此时button的点击事件不会调用jquery中的show(

JQuery this和$(this)的区别及获取$(this)子元素对象的方法

1.JQuery this和$(this)的区别 相信很多刚接触JQuery的人,很多都会对$(this)和this的区别模糊不清,那么这两者有什么区别呢? 首先来看看JQuery中的  $()  这个符号,实际上这个符号在JQuery中相当于JQuery(),即$(this)=jquery();也就是说,这样可以返回一个jquery对象.那么,当你在网页中alert($('#id'));时,会弹出一个[object Object ],这个object对象,也就是jquery对象了. 那么,我们

jquery生产和开发的区别

今天说一下jquery生产和开发的区别,在我们下载jquery的时候,会有两个下载链接,一个是jquery.min.js .迷你版 (生产),另一个是 jquery.js .开发版 .不知道的人可能就好奇了,是什么呢,其实 生产版就是把能省略的占空间的都删除了,比如空格,所有的代码都是一堆,不适合查阅,所以称为生产版,就是为 了节省空间.那么反过来开发版的jquery适合查阅和研究.两个版本的代码一模一样,只是排版有一些问题吧. 今天刚了解到jquery升级到2.0了,有一些新的特性,整体大小比

Jquery中$.post()与$.get()区别

1:GET访问 浏览器 认为 是等幂的 就是 一个相同的URL 只有一个结果[相同是指 整个URL字符串完全匹配] 所以 第二次访问的时候 如果 URL字符串没变化 浏览器是 直接拿出了第一次访问的结果 POST则 认为是一个 变动性 访问 (浏览器 认为 POST的提交 必定是 有改变的) 防止 GET 的 等幂 访问 就在URL后面加上 ?+new Date();,[总之就是使每次访问的URL字符串不一样的] 设计WEB页面的时候 也应该遵守这个原则 2:谈Ajax的Get和Post的区别

jQuery介绍 DOM对象和jQuery对象的转换与区别

jQuery介绍 DOM对象和jQuery对象的转换与区别 jQuery介绍 jQuery: http://jquery.com/ write less, do more. jQuery Hello World程序 <script type=“text/javascript” src=“xxx//jquery-x.y.z.js"> 引入jQuery.存在两个版本,jquery-x.y.z.min.js是精简压缩版,不带min的是开发版,代码中的注释和缩进等都被保留了. 注意路径中的”

jquery find()和filter()的区别

在写js查找当前标签下某一子元素的子元素集合时,用到了此方法 1 $(".flyout-trigger").mouseover(function(){ 2 var maxnum=$(this).find(".flyout-link").children().filter("dt").size(); 3 $(this).children(".flyout-link").show(); 4 $(this).children(&qu

Js - Dom原生对象和jQuery对象的联系、区别、相互转换

Dom原生对象和jQuery对象的联系.区别.相互转换: 联系: 1.jQuery对象:通过jQuery包装DOM对象后产生的对象: 2.两者之间可以相互转换:区别: 1.jquery选择器得到的jquery对象和标准的 javascript中的document.getElementById()取得的dom对象是两种不同的对象类型,两者不等价: 2.jQuery无法使用DOM对象的任何方法,同理DOM对象也不能使用jQuery里的方法. 乱使用会报错. 例如: $("#id").htm