• jQuery基本选择器模块(二)


    选择器模块

    1、push方法的兼容性(了解)

    • 问题:IE8不支持aplly方法中的第二个参数是 伪数组
    • 目标:实现 push 方法的浏览器兼容性问题
    var push = [].push;
    try {
        // 判断 push 是否可用
        var container = document.createElement("div");
        container.innerHTML = "<p></p><p></p>";
        push.apply([], container.childNodes);
    } catch(e) {
        // push不可用,则自己实现
        push = {
            apply: function(target, els) {
                var j = target.length;
                    i = 0;
                while(target[j++] = els[i++]) {}
                target.length = j - 1;
            }
        };
    } finally {
        container = null;
    }
    
    // push.apply([1, 2, 3], ["a", "b"])
    // [1, 2, 3, "a", "b"]
    
    • 优化原则:
    将 push 的判断,放入 沙箱 中
    在页面加载的时候就会执行这段代码,保证了代码只会检测一次
    以后的操作中直接使用 push 即可。
    

    2、整合JS文件

    • 目标:将已经写好的函数放到一个单独的 js 文件中去,实现代码的复用
    • 注意:代码要加注释
    get / each
    getTag / getId / getClass
    

    2.1 优化封装好的方法

    • 目标:体现复用,优化现有方法

    3、支持上下文的通用 get 函数

    • 解释:上下文(context),即当前内容的上面和下面,也就是环境
    • 目标:让 get 函数可以从指定的上下文中取出相应的元素
    • 注意:只有 document 具有 getElementById 方法
    • 思路:先从三个简单的获取函数入手(从小做起),再修改通用 get 函数
    // 只查找 context 中的 div 元素
    var elms = get("div", context);
    

    3.1 在 context 中查找元素

    • 思路:提供 context 参数
    • 推荐:函数参数顺序,按照使用频率高低的顺序排放

    3.1.1 context 是 DOM对象

    • 目标:获取 DOM对象 的后代元素
    var getTag = function(tagName, context, results) {
        context = context || document;
        // ...
    };
    // getClassName 和 get 同样修改
    

    3.1.2 context 是 DOM对象数组

    • 目标:获取 DOM对象数组中 每个DOM对象的后代元素
    • 技巧:“没有条件创造条件也要上”
    var get = function(selector, context, results) {
        results = results || [];
        context = context || document;
    
        var rquickExpr = /^(?:#([w-]+))|.([w-]+)|([w-]+)|(*))$/,
            m = rquickExpr.exec(selector);
    
        if(m) {
            if(context.nodeType) {
                context = [context];
            }
    
            each(context, function(i, v) {
                if(m[1]) {
                    results = getElmById(m[1], results);
                } else if(m[2]) {
                    results = getElmsByClsName(m[2], v, results);
                } else {
                    results = getElmsByTag(m[3] || m[4], v, results);
                }
            });
        }
        return results;
    };
    

    3.1.3 context 是字符串(选择器)

    • 思路:将 选择器 转化为 DOM对象数组
    var get = function(selector, context, results) {
        // ...
            if(typeof context === "string") {
                context = get(context);
            }
        // ...
    };
    

    4、复合选择器

    4.1 回顾jQuery的选择器

    • 选择器大致分类:
    1 基本选择器:id、class、element、*
    2 复合选择器
        * 2.1 并集选择器 ,
        * 2.2 后代选择器 > 空格
        2.3 兄弟选择器 ~ +
        2.4 过滤选择器
            基本过滤选择器 :eq() :odd :even
            属性选择器     [k = v]
    

    4.2 实现 并集选择器 和 后代选择器

    • 思路:先处理 逗号,将其分解为几个简单的部分再处理
    $(".c .c1, .dv:eq(0), div > [title]");
    

    4.2.1 处理 并集选择器

    • 思路:创建一个 select 函数,用来处理组合选择器
    // 去除两边空格函数
    var myTrim = function(str) {
        if(String.prototype.trim) {
            return str.trim();
        } else {
            return str.replace(/^s+|s+$/, "");
        }
    };
    
    // selector => "#dv, .cls"
    var select = function(selector, context, results) {
        results = results || [];
    
        var newSelectors = selector.split(",");
    
        each(newSelectors, function(i, v) {
            [].push.apply(results, get(myTrim(v), context));
        });
    
        return results;
    };
    

    4.2.2 处理后代选择器

    • 目标:获取指定上下文的符合后代选择器的子元素
      • select("s1 s2 s3", context)
    • 思路:
    list = select("s1", context);
    list = select("s2", list);
    list = select("s3", list);
    
    var select = function(selector, context, results) {
        results = results || [];
    
        var newSelectors = selector.split(",");
    
        each(newSelectors, function(i, v) {
            var list = myTrim(v).split(" "),
                c = context;
    
            each(list, function(i, v) {
                if(v !== "") {
                    c = get(v, c);
                }
            });
    
            results.push.apply(results, c);
        });
    
        return results;
    };
    

    5、选择器模块整体分析 -要实现的功能

    • 目的:回顾总结选择器模块实现的功能
    1 get 函数实现了:通过基本选择器( id, class, tag, * ) 获取DOM对象
    2 get 函数实现在某个指定上下文中获取DOM对象
    3 select 函数实现了:通过组合选择器 获取DOM对象
    4 select 函数实现了:通过后代选择器 获取DOM对象
    
    支持的选择器:
    1 基本: "#dv" ".cls" "span"
    2 上下文:select("span", "#dv")
    3 组合: select(".c1, .c2")
    4 后代: select(".c1 .c3");
    

    6、封装函数到一个对象中

    • 目标:将写好的函数封装到一个 select.js 的文件中去
    • 优化:代码复用 和 性能调优
    • 思路:使用沙箱模式,形成独立环境,并对外暴露核心函数:select
    • 注意:select 并非最终的 itcast 函数,不需要使用 window 暴露到全局环境
    var select =
    (function() {
    // ...
    
    return select;
    })();
    

    7、借用jQuery的 Sizzle 引擎

  • 相关阅读:
    Verilog设计Valid-Ready握手协议
    E203 CSR rtl实现分析
    E203 CSR寄存器
    RiscV汇编介绍(1)-编译过程
    RiscV汇编介绍(2)-编译过程
    博客迁移通知
    Visual Studio中的环境变量(以Visual Studio 2013为例)
    Android Studio搜索功能(查找功能)及快捷键图文详解
    《更好的解释(数学篇)》——后序
    《更好的解释(数学篇)》——第十二章
  • 原文地址:https://www.cnblogs.com/lsy0403/p/5910833.html
Copyright © 2020-2023  润新知