Sizzle引擎(一)-总体结构和设计思想

选择器表达式

术语约定

  1. 选择器表达式:如,"div>p"
  2. 并列选择器表达式:如,"div p"
  3. 块表达式:如,"div>p"中的"div","p"
  4. 块表达式类型:如,"div"的类型是TAG,"div.red"则是TAG+CLASS
  5. 块间关系符:如,"div>p"中的">"

选择器表达式的组成

  1. 块表达式
    1. 简单表达式:ID,CLASS,TAG
    2. 属性表达式:ATTR
    3. 伪类表达式PSEUDO:
      1. 位置伪类:POS
      2. 子元素伪类CHILD
      3. 内容伪类
      4. 可见伪类
      5. 表单伪类
  2. 块间关系符:">" , "" , "+"和"~"

查找思路:以"div.red>p"为例

查找思路
1.从左向右:先查找"div.red",再查找"p";(不断缩小查找范围)
2.从右到左(Sizzle核心查找方式):先查找:"p",再查找"div.red";(先查找后过滤,效率比从左到右高;)
步骤

  1. 解析出:块表达式和块间关系符的集合
  2. 先查找div.red元素,再查找p元素
  3. 处理div.red和p之间的关系符">"
    1. 从左到右:找到div.red匹配的子元素集合,再查找匹配p的元素
    2. 从右到左:查找匹配p元素的父元素是否为div.red

Sizzle总体架构

/**书籍:jQuery技术内幕-深入解析jQuery架构设计与实现
 * 
 * 如果浏览器支持querySelectorAll(),则调用该方法
 * 如果不支持,Sizzle模拟该方法的行为
 * 
 * 术语和约定[重点]
 * 1.选择器表达式:"div>p"
 * 2.并列选择器表达式:"div,p"
 * 3.块表达式:"div>p"中的"div","p"
 * 4.快表达式类型:div的类型是TAG, ".red"的类型类型是CLASS,"div.red"的类型是TAG+CLASS
 * 5.块间关系符:"div>p"中的>
 * 
 * 选择器表达式有块表达式和块间关系符组成
 * 1.块间关系符
 * 2.块表达式
 *  a.简单表达式:ID,CLASS,TAG
 *  b.属性表达式:ATTR
 *  c.伪类表达式:1.位置伪类:POS; 2.子元素伪类:CHILD; 3.内容伪类; 4.可见伪类; 表达伪类
 */
(function(window){
    var Expr;

//***********************公开方法***************************************** */
    /**
     * 查找与选择器表达式selector匹配的元素集合:引擎入口
     * @param {*} selector CSS选择器表达式
     * @param {*} context DOM元素或文档对象
     * @param {*} results 结果集
     * @param {*} seed 可选元素集合,Sizzle()将从该元素集合中过滤出匹配选择器表达式的元素集合
     * @returns 
     */
    function Sizzle(selector,context,results,seed){
        return results;
    };
    //用选择器表达式expr对元素集合set进行过滤
    Sizzle.matches = function( expr, elements ) {
        return Sizzle( expr, null, null, elements );
    };
    //检查元素node是否匹配选择器表达式expr
    Sizzle.matchesSelector = function( elem, expr ){

    };

//***********************内部使用********************************** */
    //选择器表达式过滤
    Expr = Sizzle.selectors = selectors;

    Expr.pseudos[ "nth" ] = Expr.pseudos[ "eq" ];

    // Easy API for creating new setFilters
    //位置伪类过滤函数集
    function setFilters() {}
    setFilters.prototype = Expr.filters = Expr.pseudos;
    Expr.setFilters = new setFilters();

    

//*******************工具方法******************************************** */
    //排序去重
    Sizzle.uniqueSort = function(results){

    };
    //检查元素a是否包含b
    Sizzle.contains = function( context, elem ) {
    };
    Sizzle.error = function(msg){
        throw new Error("Syntax error,unrecognized expression: "+msg);
    };
//********************暴露出去******************************* */
    //Expose
    var _sizzle = window.Sizzle;//未加载jQuery前的Sizzle属性
    //如果名称冲突, 用这个方法取另外的名称
    Sizzle.noConflict = function(){
        if(window.Sizzle === Sizzle)
        {
            window.Sizzle = _sizzle;
        }
        return Sizzle;
    }

    //引入方式
    if(typeof define === "function" && define.amd){//AMD(nodejs):Asynchronous Module Definitoin
        define(function(){
            return Sizzle;
        });
    }else if(typeof module !== "undefined" && module.exports){
        module.exports = Sizzle;//ES6
    }else{
        window.Sizzle = Sizzle;
    }
})(window);
最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

推荐阅读更多精彩内容