jQuery技术

jQuery选择器源码解读(八):addCombinator函数【站长博客网】(2)

字号+ 作者:H5之家 来源:H5之家 2017-04-27 16:00 我要评论( )

// We can't set arbitrary data on XML nodes, so they don't // benefit from dir caching if (xml) { while ((elem = elem[dir])) { if (elem.nodeType === 1 || checkNonElements) { if (matcher(elem, context

 // We can't set arbitrary data on XML nodes, so they don't
 // benefit from dir caching
 if (xml) {
  while ((elem = elem[dir])) {
   if (elem.nodeType === 1 || checkNonElements) {
    if (matcher(elem, context, xml)) {
     return true;
    }
   }
  }
 } else {
  while ((elem = elem[dir])) {
   if (elem.nodeType === 1 || checkNonElements) {
    outerCache = elem[expando] || (elem[expando] = {});
    if ((cache = outerCache[dir])
      && cache[0] === dirkey) {
     if ((data = cache[1]) === true
       || data === cachedruns) {
      return data === true;
     }
    } else {
     cache = outerCache[dir] = [ dirkey ];
     cache[1] = matcher(elem, context, xml)
       || cachedruns;
     if (cache[1] === true) {
      return true;
     }
    }
   }
  }
 }
};

4.2.1 功能

若检查的是XML文档,则其过程与4.1返回函数一致,见上述代码中if ( XML ) { ... }中大括号内的代码。

若是HTML文档,则根据matcher匹配当前元素,若匹配成功,返回true;否则返回false。

4.2.2 参数
elem——待检查的单个节点元素。

context——执行整个选择器字符串匹配的上下文节点,大部分时候是没有用途。

xml——当前搜索对象是HTML还是XML文档,若是HTML,则xml参数为false。

4.2.3 代码说明

内部变量

dirkey——缓存节点检测结果用的键。在一次执行过程中,若一个节点被检查过,则会在这个节点的dirkey属性(属性名称为dirkey的值)中记录下检测结果(true或false),那么在本次执行过程中,再次遇到该节点时,不需要再次检测了。之所以需要缓存,因为多个节点会存在同一个父节点或兄弟节点,利用缓存可以减少检测的次数,提高性能。

dirruns——每次执行通过matcherFromGroupMatchers组织的预编译代码时都会产生一个伪随机数,用以区别不同的执行过程。
doneName——每次执行addCombinator函数时,done变量都会加1,用以区别生成的不同的位置关系匹配函数。

cachedruns——用来记录本次匹配是第几个DOM元素。例如:div.map>span,有3个元素符合span选择器,则针对每个元素执行>匹配函数时,cachedruns依次为0、1、2。cachedruns的作用按照代码可以直接理解为在一个执行过程中,针对同一个元素使用elementMatchers进行匹配过程中,再次遇到同一个元素时,可以直接从获取不匹配的结果,但是,我想不出哪个情况下会发生这种事情。若有人遇到,请告知,多谢!

代码解释

复制代码 代码如下:


while ((elem = elem[dir])) {
 if (elem.nodeType === 1 || checkNonElements) {
  // 若elem节点的expando属性不存在,则赋予空对象,并同时赋予outerCache
  // 若elem节点的expando属性存在,则将其值赋予outerCache
  outerCache = elem[expando] || (elem[expando] = {});
  /*
   * 若outCache[dir]有值,且其第一个元素等于当前的dirkey,
   *     则说明当前位置选择器在本次执行过程中已检测过该节点,执行if内的语句,从缓存中直接获取结果
   * 若outCache[dir]不存在,或第一个元素不等于当前的dirkey,
   *     则说明当前位置选择器在本次执行过程中还未检测过该节点,执行else内的语句,匹配节点并将结果放入缓存
   */
  if ((cache = outerCache[dir])
    && cache[0] === dirkey) {
   // 若缓存中检测结果等于true或cachedruns的值,则返回检测结果(非true皆为false),
   // 否则继续循环获取上一个符合位置关系的节点进行匹配
   if ((data = cache[1]) === true
     || data === cachedruns) {
    return data === true;
   }
  } else {
   // 将数组[ dirkey ]赋予outerCache[dir]及cache
   cache = outerCache[dir] = [ dirkey ];
   // 将匹配成功,将true赋予cache[1],否则将cachedruns的值赋予cache[1]
   cache[1] = matcher(elem, context, xml)
     || cachedruns;
   // 若匹配结果为true,则返回true,否则继续循环获取上一个符合位置关系的节点进行匹配
   if (cache[1] === true) {
    return true;
   }
  }
 }
}

Tag标签:  jQuery  选择器  源码解读  A  

 

1.本站遵循行业规范,任何转载的稿件都会明确标注作者和来源;2.本站的原创文章,请转载时务必注明文章作者和来源,不尊重原创的行为我们将追究责任;3.作者投稿可能会经我们编辑修改或补充。

相关文章
  • 简洁实用的BootStrap jQuery手风琴插件

    简洁实用的BootStrap jQuery手风琴插件

    2017-04-27 09:00

  • 最新:jquery.mark

    最新:jquery.mark

    2017-04-27 08:00

  • Laravel 5 中基于 jQuery 实现分层级的类目树结构实例教程 Larav

    Laravel 5 中基于 jQuery 实现分层级的类目树结构实例教程 Larav

    2017-04-27 08:01

  • 晚报:jQuery和CSS3 360度产品预览特效

    晚报:jQuery和CSS3 360度产品预览特效

    2017-04-27 08:00

网友点评
/