jQuery选择器源码解读(八):addcombinator功能
功能addcombinator(匹配、组合、基地)1。源代码
复制代码代码如下所示:
功能addcombinator(匹配、组合、基地){
var目录= combinator.dir,checknonelements =基础
dir =parentNode
返回combinator.first
针对最近的祖先前面的元素检查
功能(元素、语境、XML){
而(((元=元{ dir })){
如果(elem.nodetype = 1 | | { checknonelements)
返回匹配(元素、语境、XML);
}
}
}:
对所有祖先/前面的元素检查
功能(元素、语境、XML){
VaR数据缓存,outercache,dirkey = dirruns ++ donename;
我们不能在xml节点上设置任意数据,所以它们不
从目录缓存
如果(XML){
而(((元=元{ dir })){
如果(elem.nodetype = 1 | | { checknonelements)
如果(匹配(元素、语境、XML)){
返回true;
}
}
}
{人}
而(((元=元{ dir })){
如果(elem.nodetype = 1 | | { checknonelements)
outercache =元素{ expando }(元{ expando } = | | { });
如果((cache = outercache { dir })
缓存{ 0 } = = = dirkey){
(数据=(缓存{ 1 } = true)
| | {数据= = = cachedruns)
返回数据=真;
}
{人}
缓存= outercache { dir } = { dirkey };
缓存{ 1 } =匹配(元素、语境、XML)
| | cachedruns;
如果(缓存{ 1 } = true){
返回true;
}
}
}
}
}
};
}
2、功能
生成关系选择器的执行函数。
三.参数
匹配——连续过滤选择器匹配函数数组之前的位置关系。这个函数是用来匹配节点是否通过位置关系符合选择要求。在实际执行中,这个功能可能是elementmatcher(匹配),已在相关选择产生的。例如,div.map >跨度,当编译器遇到嘶嘶>,div.map函数称为addcombinator函数作为第一个参数检查是否跨父节点满足div.map两条件。
组合的关系选择对应的expr.relative的价值,并在expr.relative的各种关联选择器的值如下。使用该参数的第一属性来确定是否返回的是一个只检查相邻对象的功能或遍历所有可能的目标。通过下面的代码:元素=元素{ dir },获得一个与指定的位置关系的节点,在DIR等于combinator.dir。
复制代码代码如下所示:
expr.relative:{
:{
目录:parentNode
第一:真的
},
:{
目录:父节点
},
:{
目录:PreviousSibling
第一:真的
},
:{
目录:PreviousSibling
}
}
基此参数,连同combinator.dir,确定变量的值,checknonelement,代码如下。这个值是从字面上解释为非DOM元素是目前检查。当elem.nodetype!= 1,如果值为true,它将执行匹配函数,否则,它将完成循环。
4。返回功能
4.1如果关系选择器是>或+,则返回以下函数:
复制代码代码如下所示:
功能(元素、语境、XML){
而(((元=元{ dir })){
如果(elem.nodetype = 1 | | { checknonelements)
返回匹配(元素、语境、XML);
}
}
}
4.1.1功能
如果校验节点单元类型(checknonelements = = false),元素指定迭代的位置关系获取第一个元素节点类型(elem.nodetype = = 1),匹配函数的实现,节点检查是否符合要求,如果线返回true,否则返回false;
如果我们检查所有类型的节点(即checknonelements = =真),得到相邻节点指定元素的位置关系,进行匹配功能,检查节点是否符合要求,如果我们返回真,否则我们将返回错误。
有些人可能会问,这难道不是一种亲密的关系吗为什么在代码中有一个迭代捕获过程这是因为有些浏览器会把节点之间的换行字符作为文本,所以在加工过程中,我们需要跳过这些节点到下一个元素节点。
4.1.2 parameters
样品的单节点单元进行检查。
上下文——执行整个选择器字符串匹配的上下文节点大部分时间不使用。
当前的搜索对象是一个HTML或XML文档,如果HTML,XML参数是false。
4.2如果关系选择器是~或空间,则返回以下函数:
复制代码代码如下所示:
对所有祖先/前面的元素进行检查
功能(元素、语境、XML){
VaR数据缓存,outercache,dirkey = dirruns ++ donename;
我们不能在xml节点上设置任意数据,所以它们不
从目录缓存
如果(XML){
而(((元=元{ dir })){
如果(elem.nodetype = 1 | | { checknonelements)
如果(匹配(元素、语境、XML)){
返回true;
}
}
}
{人}
而(((元=元{ dir })){
如果(elem.nodetype = 1 | | { checknonelements)
outercache =元素{ expando }(元{ expando } = | | { });
如果((cache = outercache { dir })
缓存{ 0 } = = = dirkey){
(数据=(缓存{ 1 } = true)
| | {数据= = = cachedruns)
返回数据=真;
}
{人}
缓存= outercache { dir } = { dirkey };
缓存{ 1 } =匹配(元素、语境、XML)
| | cachedruns;
如果(缓存{ 1 } = true){
返回true;
}
}
}
}
}
};
4.2.1功能
如果检查XML文档,该过程与4.1个返回函数是一致的,并在上面的代码中看到if(XML)}中的括号中的代码。
如果HTML文档,然后匹配当前元素根据匹配,并返回true,如果匹配成功;否则,将返回false。
4.2.2参数
样品的单节点单元进行检查。
上下文——执行整个选择器字符串匹配的上下文节点大部分时间不使用。
当前的搜索对象是一个HTML或XML文档,如果HTML,XML参数是false。
4.2.3代码描述
内部变量
dirkey用于缓存节点的检测结果的关键。在一个实施例中,如果一个节点被选中,将在该节点的dirkey属性(对dirkey值的属性的名称)检测结果记录(真或假),所以在实施过程中,再次遇到节点,不需要重新测试。缓存的需要是由于多个节点的同父母或兄弟节点的存在,并使用缓存可以减少检测次数,提高性能。
dirruns --伪随机数产生时,通过matcherfromgroupmatchers组织执行预编码的代码,这是用来区分不同的执行过程。
donename每次执行addcombinator功能,完成变量加1来区分不同的位置关系匹配函数,生成。
cachedruns -记录这场比赛是DOM元素的个数。例如:div.map >跨度,3元素符合跨度选择,cachedruns是0, 1,和2为每个元素进行匹配功能,cachedruns按照代码的作用可以直接解释,在实施过程中,使用匹配过程的elementmatchers相同的元素,再次遇到相同的元素,可以直接从不匹配的结果得到的,但我不认为这会发生的情况。如果有人遇见,请让我知道。谢谢您.
代码解释
复制代码代码如下所示:
而(((元=元{ dir })){
如果(elem.nodetype = 1 | | { checknonelements)
如果扩展属性 / /元素节点不存在,然后把空对象,并给出了outercache
如果扩展属性 / /元素节点,分配到outercache价值
outercache =元素{ expando }(元{ expando } = | | { });
*
*如果outcache { dir }是有价值的,和它的第一个元素等于当前dirkey,
*表示当前位置选择器在执行过程中检测到节点,在if中执行语句,并直接从缓存中获得结果。
*如果outcache } {目录不存在,或第一个元素不等于当前dirkey,
*表示当前位置选择器未检测到此执行中的节点,执行其他语句中的语句,匹配节点并将结果放入缓存中。
* /
如果((cache = outercache { dir })
缓存{ 0 } = = = dirkey){
如果缓存/检测结果等于或cachedruns真值,返回结果(真的假的),
继续循环以获得与节点匹配的位置关系一致。
(数据=(缓存{ 1 } = true)
| | {数据= = = cachedruns)
返回数据=真;
}
{人}
/ /数组{ dirkey }给outercache { dir }和缓存
缓存= outercache { dir } = { dirkey };
/ /将匹配,真正将缓存{ 1 },否则将会给cachedruns缓存{ 1 }的价值
缓存{ 1 } =匹配(元素、语境、XML)
| | cachedruns;
如果匹配结果为true,则返回true,否则继续在节点匹配之间使用圆形位置。
如果(缓存{ 1 } = true){
返回true;
}
}
}
}