除了判断的过程,那么还涉及到节点的关系处理,如:
var selector = "div > div.Aaron [name=ttt]";
节点与节点之间是有层级关系的,这里就遇到了“>”与“空”。子元素组合器(E > F)和(E F)都作为后代组合,但是他们有所不同,更具体的是(E > F)它只会选择第一级的后代,那么我们从右边往左边匹配就会遇到这样的情况,[name=ttt]节点与div.Aaron中间的连接符“空”则为后代选择器,那么意味着[name=ttt]元素的可能是div.Aaron元素的一个孩子,孙子,曾孙等。
同理div.Aaron与div的连接符是“>” 子元素选择器,这个简单只能是父子关系。除此之外,还有相邻兄弟选择器“+”与“~”,(prev + next) 和 (prev ~ siblings)之间最值得注意的不同点是他们各自的可及之范围。前者只达到紧随的同级元素,后者扩展了该达到跟随其的所有同级元素。
针对选择器的层级关系:
首先“>”与“空”是祖辈关系,这样可以理解是线型的,那么我们只要递归检测每次元素的 parentNode 属性返回指定节点的父节点。
同理“+”与“~”也是类似的兄弟关系,无非就是扩展的范围不同,所以针对层级的关系问题。
jQuery引入了词素关系:
relative: { ">": { dir: "parentNode", first: true }, " ": { dir: "parentNode" }, "+": { dir: "previousSibling", first: true }, "~": { dir: "previousSibling" } }
这里的dir可以认为是查找的一个条件,就是查找父节点还是兄弟节点,那么first的意思就是一个快速条件,因为“>”选择器是一个很明确的父子关系所以通过标记first只需要查找一层即可。我们可以看代码:
function addCombinator(elems) { var elem; while ((elem = elems['parentNode'])) { if (elem.nodeType === 1) { return elem } } };
请验证,完成请求
由于请求次数过多,请先验证,完成再次请求
打开微信扫码自动绑定
绑定后可得到
使用 Ctrl+D 可将课程添加到书签
举报