Better

Ethan的博客,欢迎访问交流

getElementsByTagName与querySelectorAll

意外的看了一篇讲解getElementsByTagName与querySelectorAll的文章,觉得可以学到不少东西。

HTMLCollection与NodeList的区别

HTMLCollection和NodeList都是DOM的节点集合;但是它们两个能够包含的元素是不太一样的,HTMLCollection只可以包含HTML元素(Element)集合,NodeList可以包含任意的节点类型,就是说NodeList不仅可以包含HTML元素集合,也可以包含像文字节点,注释节点等类型的节点集合。

实时(live)的NodeList和静态(static)的NodeList

DOM中的NodeList是一种特殊的对象,它是实时更新的;就是你对这个NodeList中的任何一个元素进行的一些操作,都会实时的更新到这个NodeList对象上面。

通过使用querySelectorAll()方法返回的NodeList集合必须是静态的,就是一旦获取到这个结果;那么这个结果不会因为后面再对这个集合中元素进行的操作而进行改变。

速度问题

因为通过getElementsByTagName获取到的NodeList是一个实时的集合,这种实时的集合,是不需要在一开始的时候就获取到所有的信息的;然而通过querySelectorAll方法获取到的的NodeList集合是一个静态的集合,这个集合相当于一个快照,就是在这个方法运行的那个时间,它所要获取的集合元素的一个快照,所以这个集合要保存大量的信息,速度自然会慢下来。

为了加深理解,我们可以这样理解:使用getElementsByTagName方法我们得到的结果就像是一个对象的索引,而通过querySelectorAll方法我们得到的是一个对象的克隆;所以当这个对象数据量非常大的时候,显然克隆这个对象所需要花费的时间是很长的。

这也给我们一些启示,在以后需要用到获取元素集合的方法的时候,我们就要根据不同的场景来选择使用不同的方法了。如果你不需要一个快照,那就选择使用getElementsByTagName方法,如果你需要一个快照来进行复杂的CSS查询,或者复杂的DOM操作的话,那就选择使用querySelectorAll方法。

时间验证

time&timeEnd

console.time('getElementsByTagName: ');
let l1 = document.getElementsByTagName('a');
console.timeEnd('getElementsByTagName: ');

Performance

let t2 = window.performance.now();
let l2 = document.querySelectorAll('a');
let t3 = window.performance.now();


留言