标签:des blog http io ar 使用 sp for on
querySelector
,querySelectorAll
(HTML5)Document
,DocumentFragment
和Element
追加了querySelector
和querySelctorAll
,原型为Element? querySelector(DOMString selectors)
和 NodeList querySelectorAll(DOMString selectors)
,说明了匹配的算法find
和findAll
,但目前在各大浏览器里暂无实现(这个标准目前还未进入recommendation)。querySelector
及querySelectorAll
定义在了interface ParentNode
并声明Document
, DocumentFragment
及Element
均需实现这个interface,原型为Element? querySelector(DOMString selectors)
与[NewObject] NodeList querySelectorAll(DOMString selectors)
,并定义了scope-match
的步骤。注意interface ParentNode
还有用于获取相对位置的元素的两个方法query
和queryAll
,但目前在各大浏览器里暂无实现。interface ParentNode
,和WHATWG类似querySelectorAll
返回的一定是一个static NodeList
-- 也就是说如果将它的返回结果保存下来,当文档更新时,保存的NodeList
里的元素不会跟着更新。SYNTAX_ERR
异常。Selector API Level 2 和 WHATWG 改为了 SyntaxError
。:after
,:before
,:first-letter
,:first-line
,:selection
)将不会匹配到任何元素,另外出于保护隐私的考虑,标准也推荐将所有链接视为未访问,即:visited
不会匹配到任何元素。querySelector
返回null
,querySelectorAll
返回空的NodeList
querySelector
返回按照document order(先序DFS)遍历到的第一个元素,querySelectorAll
返回按照 document order 排序的NodeList
IE 9+及其他浏览器的现行版本正常支持包括CSS3的选择器,IE8支持简单的 CSS2 选择器(如:不支持空格表示的后代)
ContainerNode
就是 WHATWG 里描述的 interface ParentNode
,ContainerNode
的querySelector
和querySelctorAll
实际上分别调用SelectorQuery
的queryFirst
和queryAll
(参考WebCore/dom/ContainerNode.cpp),它们又分别调用SelectorDataList
的queryFirst
和queryAll
(注意SingleElementExtractorSelectorQueryTrait
和AllElementExtractorSelectorQueryTrait
这两个使用模版达到类似动态类型的写法挺有趣的),通过execute
来对ContainerNode
的子节点匹配CSS。execute
里就是CSS选择器的代码,里面还有相当一部分 JIT 的优化,这里就不展开分析了。
在queryFirst
用于SelectorQueryTrait
的 template specialiation 的 SingleElementExtractorSelectorQueryTrait
里,shouldOnlyMatchFirstElement
设为true
,注意execute
用于匹配CSS的其他方法基本都会在第一次找到匹配元素的时候检查shouldOnlyMatchFirstElement
确定是否立刻保存匹配结果并返回(使用elementDescendants
达到先序DFS,elementDescendants
最终也是和getElementsByID
的实现一样使用到了NodeTraversal
),这样就达到了标准里提到的返回先序DFS遇到的第一个匹配元素的要求。而queryAll
使用了StaticElementList
(StaticNodeList
),来为保存匹配元素的Vector
(属于WTF)创建一个 static 的快照用于返回(参见WebCore/dom/SelectorQuery.cpp)
NCZ的博客上讨论了为何StaticNodeList
会相对慢很多(不过上面用的是几年前的代码,现在的代码用的是WTF的Vector
的swap
(底层调用std::swap
)通过交换元素来实现复制,参见Source/WTF/wtf/Vector.h)
jQuery也有一个关于querySelectorAll
性能问题的 Open issue。
跟随标准与Webkit源码探究DOM -- 获取元素之querySelector,querySelectorAll
标签:des blog http io ar 使用 sp for on
原文地址:http://www.cnblogs.com/joyeecheung/p/4122959.html