querySelectorAll 方法相比 getElementsBy 系列方法有什么区别
来源:互联网 发布:淘宝网电话 编辑:程序博客网 时间:2024/05/23 22:08
感谢 http://www.zhihu.com/question/24702250 简生 的回答
1. W3C 标准
querySelectorAll 属于 W3C 中的 Selectors API 规范。而 getElementsBy 系列则属于 W3C 的 DOM 规范。
2. 浏览器兼容
querySelectorAll 已被 IE 8+、FF 3.5+、Safari 3.1+、Chrome 和 Opera 10+ 良好支持 。
getElementsBy 系列,以最迟添加到规范中的 getElementsByClassName 为例,IE 9+、FF 3 +、Safari 3.1+、Chrome 和 Opera 9+ 都已经支持该方法了。
3. 接收参数
querySelectorAll 方法接收的参数是一个 CSS 选择符。而 getElementsBy 系列接收的参数只能是单一的className、tagName 和 name。代码如下:
var c1 = document.querySelectorAll('.b1 .c');var c2 = document.getElementsByClassName('c');var c3 = document.getElementsByClassName('b2')[0].getElementsByClassName('c');
需要注意的是,querySelectorAll 所接收的参数是必须严格符合 CSS 选择符规范的。所以下面这种写法,将会抛出异常。代码如下
try { var e1 = document.getElementsByClassName('1a2b3c'); var e2 = document.querySelectorAll('.1a2b3c');} catch (e) { console.error(e.message);}console.log(e1 && e1[0].className);console.log(e2 && e2[0].className);
4. 返回值
大部分人都知道,querySelectorAll 返回的是一个 Static Node List,而 getElementsBy 系列的返回的是一个 Live Node List。
看看下面这个经典的例子 dome1 dome2
// Demo 1var ul = document.querySelectorAll('ul')[0], lis = ul.querySelectorAll("li");for(var i = 0; i < lis.length ; i++){ ul.appendChild(document.createElement("li"));}// Demo 2var ul = document.getElementsByTagName('ul')[0], lis = ul.getElementsByTagName("li"); for(var i = 0; i < lis.length ; i++){ ul.appendChild(document.createElement("li")); }
因为 Demo 2 中的 lis 是一个动态的 Node List, 每一次调用 lis 都会重新对文档进行查询,导致无限循环的问题。
而 Demo 1 中的 lis 是一个静态的 Node List,是一个 li 集合的快照,对文档的任何操作都不会对其产生影响
但为什么要这样设计呢?
其实,在 W3C 规范中对 querySelectorAll 方法有明确规定
The NodeList object returned by the querySelectorAll() method must be static ([DOM], section 8).
那什么是 NodeList 呢?
W3C 中是这样说明的
The NodeList interface provides the abstraction of an ordered collection of nodes, without defining or constraining how this collection is implemented. NodeList objects in the DOM are live.
所以,NodeList 本质上是一个动态的 Node 集合,只是规范中对 querySelectorAll 有明确要求,规定其必须返回一个静态的 NodeList 对象。
我们再看看在 Chrome 上面是个什么样的情况:
document.querySelectorAll('a').toString(); // return "[object NodeList]"document.getElementsByTagName('a').toString(); // return "[object HTMLCollection]"
这里又多了一个 HTMLCollection 对象出来,那 HTMLCollection 又是什么?
HTMLCollection 在 W3C 的定义如下:
An HTMLCollection is a list of nodes. An individual node may be accessed by either ordinal index or the node's name or id attributes.
Note: Collections in the HTML DOM are assumed to be live meaning that they are automatically updated when the underlying document is changed.
实际上,HTMLCollection 和 NodeList 十分相似,都是一个动态的元素集合,每次访问都需要重新对文档进行查询。两者的本质上差别在于,HTMLCollection 是属于 Document Object Model HTML 规范,而 NodeList 属于 Document Object Model Core 规范。
这样说有点难理解,看看下面的例子会比较好理解 dome
var ul = document.getElementsByTagName('ul')[0], lis1 = ul.childNodes, lis2 = ul.children;console.log(lis1.toString(), lis1.length); // "[object NodeList]" 11console.log(lis2.toString(), lis2.length); // "[object HTMLCollection]" 4
NodeList 对象会包含文档中的所有节点,如 Element、Text 和 Comment 等。
HTMLCollection 对象只会包含文档中的 Element 节点。
另外,HTMLCollection 对象比 NodeList 对象 多提供了一个 namedItem 方法。
所以在现代浏览器中,querySelectorAll 的返回值是一个静态的 NodeList 对象,而 getElementsBy 系列的返回值实际上是一个 HTMLCollection 对象 。
- querySelectorAll 方法相比 getElementsBy 系列方法有什么区别
- querySelectorAll 方法相比 getElementsBy 系列方法有什么区别
- querySelectorAll 方法相比 getElementsBy 系列方法有什么区别?
- querySelectorAll 方法相比 getElementsBy 系列方法有什么区别?
- querySelectorAll 与 getElementsBy 的区别
- JS中querySelectorAll和getElementsBy系列的分别
- querySelectorAll 和 getElementByTagName()等方法的区别
- markdown和 html相比有什么区别
- xgboost 相比GBDT有什么区别
- 生成对抗网络(GAN)相比传统训练方法有什么优势?(一)
- vb.net与c#相比有什么优势和区别?
- markdown和 html相比有什么(优点)区别?
- 事件和方法有什么区别?
- sendRedirect()和forward()方法有什么区别?
- "=="和equals方法究竟有什么区别? —— Java经典面试题系列
- document.querySelector和querySelectorAll方法
- document.querySelector和querySelectorAll方法
- 虚拟方法和抽象方法有什么区别?
- xmpp在企业通信的应用
- javascript数组的常用方法总结
- Remove Duplicates from Sorted Array II
- Linux系统之文件目录结构
- 对IDE依赖的一些看法
- querySelectorAll 方法相比 getElementsBy 系列方法有什么区别
- 栈和队列实验
- Android禁止横竖屏切换或禁止横竖屏切换时重启Activity
- 【记录】数控程序的指令代码---标准G代码与标准M代码
- fflush(stdin)和fflush(stdout)函数
- 2014-11-6Android学习------SurfaceView的框架源码
- 使用HGE粒子系统编辑器界面
- typedef 总结(2)
- Android架构师素养