querySelectorAll 方法相比 getElementsBy 系列方法区别
最近有人问到querySelectorAll 方法相比 getElementsBy 系列方法区别,一时没想起来说些什么,今天查下文档,总结一下它们的区别,以便自己理解。
querySelectorAll 属于 W3C 中的 Selectors API 规范 [1]。而 getElementsBy 系列则属于 W3C 的 DOM 规范 [2]。
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+ 都已经支持该方法了
querySelectorAll 方法接收的参数是一个 CSS 选择符。而 getElementsBy 系列接收的参数只能是单一的className、tagName 和 name。代码如下 [3]:
var c1 = document.querySelectorAll('.b1 .c');
var c2 = document.getElementsByClassName('c');
var c3 = document.getElementsByClassName('b2')[0].getElementsByClassName('c');
需要注意的是,querySelectorAll 所接收的参数是必须严格符合 CSS 选择符规范的。所以下面这种写法,将会抛出异常。代码如下 [4]:
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);
(CSS 选择器中的元素名,类和 ID 均不能以数字为开头。大家命名要规范)
4. 返回值
大部分人都知道,querySelectorAll 返回的是一个 Static Node List,而 getElementsBy 系列的返回的是一个 Live Node List。
看看下面这个经典的例子 [5]:
// Demo 1
var ul = document.querySelectorAll('ul')[0],
lis = ul.querySelectorAll("li");
for(var i = 0; i < lis.length ; i++){
ul.appendChild(document.createElement("li"));
} // Demo 2
var 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 方法有明确规定 [6]:
The NodeList object returned by the querySelectorAll() method must be static ([DOM], section 8).
那什么是 NodeList 呢?
W3C 中是这样说明的 [7]:
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 对象。 普遍观点是getXXX的性能比querySelectorAll要好很多,对于处理简单选择器的情况下非常建议fallback到它们(比如zepto就是这么做的)。
querySelectorAll 方法相比 getElementsBy 系列方法区别的更多相关文章
- [label][转载][JavaSript]querySelectorAll 方法相比 getElementsBy 系列方法有什么区别?
轉載出處: http://www.zhihu.com/question/24702250 querySelectorAll 相比下面这些方法有什么区别? getElementsByTagName g ...
- querySelectorAll 方法相比 getElementsBy 系列方法有什么区别
感谢 http://www.zhihu.com/question/24702250 简生 的回答 1. W3C 标准 querySelectorAll 属于 W3C 中的 Selectors API ...
- querySelector系列方法相比 getElementsBy 系列方法有什么区别?
querySelector 和 querySelectorAll 相比下面这些方法有什么区别? getElementsByTagName getElementsByClassName getElem ...
- getElementsBy 系列方法相比querySelector系列的区别
最近在做的项目中,使用querySelectorAll获取了同class名的元素后,绑定onmouseover事件和onmouseout后,多次在几个元素上移入移出操作时,控制台出现了报错的问题,最后 ...
- querySelectorAll 方法和 getElementsBy 系列方法的区别
本文是我在知乎上的一个回答:http://www.zhihu.com/question/24702250/answer/28695133 ————— 下面是正文 ————— 1. W3C 标准quer ...
- querySelector.. 方法相比 getElementsBy..
querySelectorAll 返回的是一个 Static Node List,而 getElementsBy 系列的返回的是一个 Live Node List. 看看下面这个经典的例子 [5]: ...
- ReactiveSwift源码解析(九) SignalProducerProtocol延展中的Start、Lift系列方法的代码实现
上篇博客我们聊完SignalProducer结构体的基本实现后,我们接下来就聊一下SignalProducerProtocol延展中的start和lift系列方法.SignalProducer结构体的 ...
- xorm -sum 系列方法实例
求和数据可以使用Sum, SumInt, Sums 和 SumsInt 四个方法,Sums系列方法的参数为struct的指针并且成为查询条件. package main import ( " ...
- MethodHandle(方法句柄)系列之三:invoke和invokeExact的区别
先把代码贴上来,用的是一样的代码 /** * * @author LiuYeFeng<897908343@qq.com> * @date 2015年4月8日 下午10:41:13 * @C ...
随机推荐
- 「译」JUnit 5 系列:环境搭建
原文地址:http://blog.codefx.org/libraries/junit-5-setup/ 原文日期:15, Feb, 2016 译文首发:Linesh 的博客:环境搭建 我的 Gith ...
- JQuery阻止事件冒泡
冒泡事件就是点击子节点,会向上触发父节点,祖先节点的点击事件. 我们在平时的开发过程中,肯定会遇到在一个div(这个div可以是元素)包裹一个div的情况,但是呢,在这两个div上都添加了事件,如果点 ...
- 借助 SIMD 数据布局模板和数据预处理提高 SIMD 在动画中的使用效率
原文链接 简介 为发挥 SIMD1 的最大作用,除了对其进行矢量化处理2外,我们还需作出其他努力.可以尝试为循环添加 #pragma omp simd3,查看编译器是否成功进行矢量化,如果性能有所提升 ...
- 2DToolkit官方文档中文版打地鼠教程(三):Sprite Collections 精灵集合
这是2DToolkit官方文档中 Whack a Mole 打地鼠教程的译文,为了减少文中过多重复操作的翻译,以及一些无必要的句子,这里我假设你有Unity的基础知识(例如了解如何新建Sprite等) ...
- [异常特工]android常见bug跟踪
前言 对app的线上bug的收集(友盟.云捕等)有时会得到这样的异常堆栈信息:没有一行代码是有关自身程序代码的.这使得对bug的解决无从下手,根据经验,内存不足OOM,Dialog关闭,ListVie ...
- Lesson 20 One man in a boat
Text Fishing is my favourite sport. I often fish for hours without catching anything. But this does ...
- .NET基础拾遗(2)面向对象的实现和异常的处理基础
Index : (1)类型语法.内存管理和垃圾回收基础 (2)面向对象的实现和异常的处理基础 (3)字符串.集合与流 (4)委托.事件.反射与特性 (5)多线程开发基础 (6)ADO.NET与数据库开 ...
- Nginx 配置简述
不论是本地开发,还是远程到 Server 开发,还是给提供 demo 给人看效果,我们时常需要对 Nginx 做配置,Nginx 的配置项相当多,如果考虑性能配置起来会比较麻烦.不过,我们往往只是需要 ...
- 【原】得心应手小工具开发——IE代理快速切换工具
一.引入 因为公司里上外网要经常换IE代理地址,每次切换地址都要进到Internet Options里去设置一番,经常切换的话很是麻烦,由于用了点时间作个小工具来方便自己. 二.实现思路 其实思路很简 ...
- 网站使用https协议
了解https HTTPS 是以安全为目标的 HTTP 通道,即 HTTP 下加入 SSL 加密层.HTTPS 不同于 HTTP 的端口,HTTP默认端口为80,HTTPS默认端口为443. SSL ...