querySelector/querySelectorAll遍历元素的顺序

问题背景

  在前端项目开发中,querySelector/querySelectorAll经常被用来选择目标元素。最近笔者在开发图片轮播组件时使用querySelectorAll来选择待轮播的图片元素,然后拟将返回的列表中元素的排列顺序当做元素被插入html文档的顺序。这时有一个问题不禁困扰着笔者,querySelectorAll返回的元素列表中的元素究竟是以何种顺序排列?是否与笔者期望的排列顺序相同?带着疑问,笔者查阅了相关资料,弄清楚了querySelector/querySelectorAll遍历元素的顺序。

问题解答

  关于querySelector/querySelectorAll遍历元素的顺序,Selectors API标准文档已经进行了详细的描述:

The querySelector() methods on the Document, DocumentFragment, and Element interfaces must return the first matching Element node within the subtrees of the context node. If there is no matching Element, the method must return null.

The querySelectorAll() methods on the Document, DocumentFragment, and Element interfaces must return a NodeList containing all of the matching Element nodes within the subtrees of the context node, in document order. If there are no matching nodes, the method must return an empty NodeList.

  根据标准文档的描述,可以作如下总结:querySelectorAll按照文档顺序(document order)来遍历所有元素,并且将查找到的目标元素依次存储到一个列表,最后返回该列表;querySelector只返回查找到的第一个目标元素。
  标准文档对文档顺序的定义也有一个详细的描述:

The term document order means a depth-first pre-order traversal of the DOM tree or subtree in question.

  根据标准文档的描述,文档顺序是按照深度优先结合先序遍历的方式遍历DOM树及其子树的顺序
  DOM树构建时元素节点的插入顺序直接影响了querySelector/querySelectorAll遍历元素的顺序。浏览器构建DOM树时元素节点的插入顺序又是怎样的呢?
  来自以色列的开发者Tali Garsiel花了大量时间研究开源浏览器的源码,根据Tali Garsiel的研究成果以及html5标准文档可以了解到,浏览器是按照html文档字节流的顺序来解析html文档并生成DOM树的。元素节点插入到DOM树的顺序是元素标签在html文档字节流中出现的先后顺序。
  根据上述内容可以得出如下结论:querySelector/querySelectorAll遍历元素的顺序与元素标签在html文档字节流中出现的顺序一致