zoukankan      html  css  js  c++  java
  • jQuery基本选择器模块

    选择器模块

    1、获取元素的基本操作

    • 案例:给页面中的div和p设置边框样式

    1.1 传统方式 -获取元素并设置样式

    实现思路

    • 1 通过 标签名 获取元素
    • 2 遍历循环 设置样式
    var dvs = document.getElementsByTagName("div"),
        ps  = document.getElementsByTagName("p"),
        i = 0, j = 0, 
        dvLen = dvs.length,
        pLen = ps.length;
    
    for(; i < dvLen; i++) {
        dvs[i].style.border = "1px solid red";
    }
    for(; j < pLen; j++) {
        ps[j].style.border = "1px solid red";
    }
    
    • 小结:传统方式存在的不足
    1 代码冗余
    2 没有实现复用
    3 错误率高
    4 效率低
    5 性能不好
    

    1.2 使用函数 -获取元素并设置样式

    • 优势:函数的复用
    • 注意:函数命名,达到 “顾名思义” 的效果
    var getElmsByTag = function(tagName) {
        return document.getElementsByTagName(tagName);
    };
    
    var dvs = getElmsByTag("div");
    var ps = getElmsByTag("p");
    
    // for 循环遍历两次来设置样式
    

    1.3 封装 each 函数

    • 目标:只要是能用循环完成的操作 each 函数都能完成

    1.3.1 使用 each 函数简化设置样式

    // 1 将 for 循环封装成 each 函数
    var each = function(arr) {
        for(var i = 0; i < arr.length; i++) {
            arr[i].style.border = "1px solid red";
        }
    };
    
    // 2 修改 each 函数的功能 实现修改任何样式
    var each = function(arr, style, value) {
        for(var i = 0; i < arr.length; i++) {
            arr[i].style[ style ] = value;
        }
    };
    
    • 不足:只能修改样式
    var arr = [1, 3, 5, 7, 10, 9, 8];
    例如:求和、求最大值、查找某值的索引号 等等
    写出以上练习,并找出其中相同点(抽象的能力)
    

    1.3.2 重新封装each函数 -1(添加回调函数)

    • 目标:在回调函数中能访问到数组中每一项和索引号(使用参数)
    var each = function(arr, fn) {
        var i = 0,
            len = arr.length;
        for(;i < len; i++) {
            fn(i, arr[i]);
        }
    };
    

    1.3.3 重新封装each函数 -2(添加跳出循环)

    • 目标:让循环的终止可控
    var each = function(arr, fn) {
        var i = 0,
            len = arr.length;
        for(; i < len; i++) {
            if(fn(i, arr[i]) === false) {
                break;
            }
        }
    };
    

    1.3.4 重新封装each函数 -3(添加this支持)

    • 目标:在函数内部使用 this 表示当前元素
    var each = function(arr, fn) {
        var i = 0,
            len = arr.length;
        for(;i < len; i++) {
            if(fn.call(arr[i], i, arr[i]) === false) {
                break;
            }
        }
    };
    
    • 练习:使用封装好的each遍历元素设置样式

    1.4 封装 getElmsByTag 函数(使用容器存储结果)

    • 目标:调用方法获得任意个结果(心想事成)

    1.4.1 重新封装 getElmsByTag 函数

    var getElmsByTag = function(tagName, results) {
        results = results || []; // 设置默认值
    
        results.push.apply(results, document.getElementsByTagName(tagName));
        return results;
    };
    
    • 验证优化之后的 get 函数:
    each(getElmsByTag("div", getElmsByTag("p")), function() {
        this.style.background = "green";
    });
    

    2、封装通用 get 函数 -通过基本选择器获取元素

    • 思路:实现get函数的两种方式
    1 在原来的函数中直接修改
    2 写一个新的函数,如果要通过标签名获取,则直接调用 getElmsByTag
    
    推荐使用第二种方式
    原因:获取元素的函数可能有多个,例如:通过id获取的函数/通过标签名获取/通过类名获取
    

    2.1 封装 id/className 函数

    • 目标:封装函数实现通过 id 或者 类名 来获取元素

    2.1.1 封装getElmById函数 -通过id获取元素

    var getElmById = function(id, results) {
        results = results || [];
        results.push( document.getElementById(id) );
    
        return results;
    };
    

    2.1.2 封装getElmsByClsName函数 - 通过类名获取元素

    var getElmsByClsName = function(clsName, results) {
        results = results || [];
        results.push.apply(results, document.getElementsByClassName(clsName));
    
        return results;
    };
    

    2.2 封装get函数

    • 目标:通用函数能通过 id/类名/标签名 获取元素
    var get = function(selector, results) {
        results = results || [];
    
        var rquickExpr = /^(?:#([w-]+)|.([w-]+)|([w-]+)|(*))$/,
            m = rquickExpr.exec(selector);
    
        if(m) {
            if(m[1]) {
                results = getElmById(m[1], results);
            } else if(m[2]) {
                results = getElmsByClsName(m[2], results);
            } else {
                results = getElmsByTag(m[3] || m[4], results);
            }
        }
    
        return results;
    };
    

    3、实现兼容 getElementsByClassName 函数

    • 目标:封装 className 函数兼容所有浏览器
    • 问题:
    1 方法存在兼容性,IE8 及以下的浏览器不支持此方法
    2 如何判断浏览器不支持该方法
    3 如何实现该方法
    

    3.1 浏览器能力检测

    • 注意:
    1 能力只需要检测一次即可
    2 能力检测当心函数重写问题
    
    • 思路:
    1 提供一个:support 对象
    2 对象中提供与被检测方法同名的属性,其值为布尔值
    3 在js被加载的时候,就进行能力判断且只判断一次,并将判断的结果进行存储
    4 凡是要用到能力检测的地方直接使用该对象
    
    var support = {};
    support.getElementsByClassName = !!document.getElementsByClassName;
    

    3.2 检测 getElementsByClassName(了解,不做要求)

    • 目标:不仅判断有没有这个方法,还要判断能力是否符合要求
    var support = {};
    
    support.getElementsByClassName = function() {
        var isExist = false,
            tempDiv = null, tempClsName;
        isExist = !!document.getElementsByClassName;
    
        if(!isExist || typeof document.getElementsByTagName !== "funtion") {
            return false;
        }
    
        tempDiv = document.createElement("div");
        tempClsName = "itcast_" + Math.random();
        tempDiv.className = tempClsName;
    
        document.body.appendChild(tempDiv)
    
        isExist = document.getElementsByClassName(tempClsName)[0] === tempDiv;
    
        document.body.removeChild(tempDiv);
    
        return isExist;
    }();
    

    3.2.1 jQuery中的实现

    support.getElementsByClassName = function() {
        // function getElementsByClassName() { [native code] }
        var rnative = /^[^{]+{s*[native w/;
        return rnative.test(document.getElementsByClassName);
    }();
    

    3.3 实现兼容 getElementsByClassName 函数

    • 思路:
    1 通过 标签名 获取到所有元素
    2 遍历集合,通过判断元素的 className 属性,看下是否符合要求
    3 符合要求的添加到 数组 中
    4 将数组返回
    
    • 技巧:类名两端加空格,然后使用indexOf判断代替for循环
    var getElmsByClsName = function (className, results) {
        results = results || [];
    
        var allNodes, i, len, cNode;
    
        if(document.getElementsByClassName) {
            results.push.apply(results, 
                document.getElementsByClassName(className));
        } else {
            allNodes = document.getElementsByTagName("*");
    
            for(i = 0, len = allNodes.length; i < len; i++) {
                cNode = allNodes[i];
                if((" " + cNode.className + " ")
                    .indexOf(" " + className + " ") > -1) {
                    results.push(cNode);
                }
            }
        }
    
        return results;
    };
  • 相关阅读:
    UNIX环境高级编程——信号说明列表
    [Fiddler]如何让Fiddler可以抓取https的请求
    [Cookie] Read Cookie and Pass in headers
    [Training Video
    [Training Video
    [Training Video
    [Training Video
    [Training Video
    [Training Video
    [Training Video
  • 原文地址:https://www.cnblogs.com/lsy0403/p/5910820.html
Copyright © 2011-2022 走看看