您的位置:首页 > 教程笔记 > 前端笔记

jQuery源码分析之Sizzle方法

2023-12-04 13:41:20 前端笔记 36

下面是jQuery源码关于Sizzle方法分析。

分析文字并没有和源码分离,而是作为注释的方式存在,比较便于阅读。

代码:

jQuery.extend({
        /*
            DOM遍历的三个核心函数:
            jQuery.dir(elem,dir,until)         :从一个元素触发,迭代检索某个方向上的所有元素并记录,知道与遇到docuemnt对象或遇到until匹配的元素
            jQuery.nth(cur,result,dir,elem)    :从一个元素触发,迭代检索某个方向上的第N个元素
            jQuery.sibling(n,elem)            :元素n的所有后续兄弟元素,包含n,不包含elem

        */
        /*
            迭代条件:cur.nodeType !== 9 && !jQuery(cur).is(until)
            elem:    起始元素
            dir:    迭代方向,可选值:parentNode  nextSibling previousSibling
            until     选择器表达式 如果遇到until匹配的元素 迭代终止
        */
        dir:function(elem,dir,until){//支持遍历祖先 所有兄长 所有兄弟
            var matched = [],//匹配结果
                cur = elem[dir];//第一次访问  在dir方向上取一次 为循环提供第一次判断
                //不包含自身
                /*
                    迭代访问 知道遇到document对象或遇到until匹配的元素
                    cur.nodeType !== 9  当前DOM节点cur不是document对象  nodeType = 1 是element
                    !jQuery(cur).is(until) 当前DOM节点cur不匹配表达式until

                    这里或运算的过程中  满足这个条件until !==undefined && cur.nodeType ===1才会调用jQuery.is
                */
            while(cur && cur.nodeType !== 9 && (until === undefined || cur.nodeType !== 1 || !jQuery(cur).is(until))){
                if(cur.nodeType === 1){//如果是Element元素 则放入匹配结果数组
                    matched.push(cur);//符合要求 放入数组
                }
                cur = cur[dir];//将方向dir上的下一个节点 设置为当前节点 继续访问
            }
            return matched;
        },
        /*
            从一个元素触发,迭代检索某个方向上的第N个元素

            cur 起始元素
            result第几个 1表示当前元素 2表示下一个
            dir 迭代方向
            elem 多余
        */
        nth:function(cur,result,dir,elem){
            result = result || 1;//默认为从1开始
            var num =0;

            for(;cur;cur = cur[dir]){//先判断再取,结果中包含n
                //检索到了这个元素
                if(cur.nodeType === 1 && ++ num === result){
                    break;
                }
            }
            //如果result为0 或者1 取当前元素
            //如果result小于0  则放回undefined
            return cur;
        },
        /*
            元素n的所有后续兄弟元素 包含n  不包含elem
            n 起始元素
            elem排除元素
        */
        sibling:function(n,elem){
            var r = [];
            for(;n;n = n.nextSibling){//先判断再取,结果中包含n
            //过滤掉其他的Text Attr Comment等元素
                if(n.nodeType === 1 && n !== elem){
                    r.push(n);
                }
            }
            return r;
        }
});

相关推荐