Math.pow(1.1, Day)

Sizzle浅析-4

上篇文章主要分析了Sizzle对于各种情况的处理流程。在其过程中用到了频繁使用了查询(find)和过滤方法,本篇主要分析查询方法。

###查找器–Sizzle.find 变量解释:

  • Expr.order: 预定义的查询顺利,依次是ID, CLASS, NAME, TAG
  • Expr.leftMatch: 描述各类选择器的正则表达式(它是Expr.match的扩展版,前面有提到)
  • Expr.find: 核心选择器函数

    //Sizzle.find 入口 Sizzle.find = function (expr, context, isXML) { // …

      // 根据查询顺序依次用各种选择器的正则匹配,匹配成功则从Expr.find获取对应的方法进行查找。
      for (var i = 0, l = Expr.order.length; i < l; i++) {
          var match, type = Expr.order[i];
          if ((match = Expr.leftMatch[type].exec(expr))) {
              var left = match[1];
              match.splice(1, 1);
              if (left.substr(left.length - 1) !== "\\") {
                  match[1] = (match[1] || "").replace(/\\/g, "");
                  set = Expr.find[type](match, context, isXML);
    
                  if (set != null) {
                      expr = expr.replace(Expr.match[type], "");
                      break;
                  }
              }
          }
      }
      if (!set) {
          set = context.getElementsByTagName("*");
      }
      // 返回已查询到的结果和剩余的表达式
      return { set: set, expr: expr };   };
    

Sizzle.find只是DOM查找的一个外部方法,具体实现交给Expr.find完成。下面的源码中并没有给出CLASS的实现,这是因为Sizzle做了向后兼容,如果检查到浏览器支持querySeletorAll,就会调用浏览器原生API。

//find核心方法
var Expr.find = {
    ID: function (match, context, isXML) {
        if (typeof context.getElementById !== "undefined" && !isXML) {
            var m = context.getElementById(match[1]);
            return m && m.parentNode ? [m] : [];
        }
    },

    NAME: function (match, context) {
        // code...
    },

    TAG: function (match, context) {
        return context.getElementsByTagName(match[1]);
    }
};

本篇文章主要分析了Sizzle.find的处理逻辑。过滤方法留在下一篇中分析。