Jquery探秘

$ 选择器的实现

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <meta http-equiv="X-UA-Compatible" content="ie=edge">
    <title>Document</title>
    <script src="js/Jquery.js"></script>
    <style>
        .active {
    
    
            background: red;
        }
    </style>
</head>
<body>
<a>链接</a>    
<button class="active">按钮1</button>
<button>按钮2</button>
<button>按钮3</button>
<button>按钮4</button>
<script>
    // 类中的this 指向我们的实例化对象
class 央央{
    
    
    constructor(arg){
    
    
        // 判断参数类型
        if(typeof arg === "string"){
    
     //如果是一个字符串类型,就先获取元素然后通过 setElement 把元素都绑定在 this 上
            let ele = document.querySelectorAll(arg);
            this.setElement(ele);
        } else if(typeof arg === "object"){
    
     //如果是一个对象类型,就通过 setElement 把元素都绑定在 this 上
            this.setElement(arg);
        } else if(typeof arg === "function"){
    
    //如果传入的是一个 function 就在文档读完之后执行这个函数
            // DOMContentLoaded 文档读完
            // onload 资源也都加载完
            window.addEventListener("DOMContentLoaded",arg);
        }
    }
    setElement(eles){
    
    
        if(eles.length === undefined){
    
     // 当 eles 只是一个元素的时候
            this[0] = eles;
            this.length = 1;
            // 把这个元素加 this 上,并被给 this 加length 变成一组元素,方便后续的逻辑处理
        } else {
    
    
            // 如果 eles 一组元素,就把每一个都加在 this 上
            for(let i = 0; i < eles.length;i++){
    
    
                this[i] = eles[i];
            }
            this.length = eles.length;
            // 给this加 length,方便后边循环
        }
    }
    click(fn){
    
     //JQ 对象上所有元素添加一个点击的处理
       for(let i = 0; i < this.length; i++){
    
    
            this[i].addEventListener("click",fn);
       }
    }
}    
function $(...arg){
    
    
    return new 央央(...arg);
} 
let btns = document.querySelector("button");
$(btns[0]).click(function(){
    
    
    console.log(this);
});
</script>    
</body>
</html>

JQ的链式操作

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <meta http-equiv="X-UA-Compatible" content="ie=edge">
    <title>Document</title>
    <script src="js/Jquery.js"></script>
    <style>
        .active {
    
    
            background: red;
        }
    </style>
</head>
<body>
<a>链接</a>    
<button class="active">按钮1</button>
<button>按钮2</button>
<button>按钮3</button>
<button>按钮4</button>
<script>
class 央央{
    
    
    constructor(arg){
    
    
        if(typeof arg === "string"){
    
     
            let ele = document.querySelectorAll(arg);
            this.setElement(ele);
        } else if(typeof arg === "object"){
    
     
            this.setElement(arg);
        } else if(typeof arg === "function"){
    
    
            window.addEventListener("DOMContentLoaded",arg);
        }
    }
    eq(index){
    
    
        return $(this[index]);
    }
    setElement(eles){
    
    
        if(eles.length === undefined){
    
    
            this[0] = eles;
            this.length = 1;
        } else {
    
    
            for(let i = 0; i < eles.length;i++){
    
    
                this[i] = eles[i];
            }
            this.length = eles.length;
        }
    }
    click(fn){
    
     
       for(let i = 0; i < this.length; i++){
    
    
            this[i].addEventListener("click",fn);
       }
       // 类的原型中的方法, this 指向 实例化对象
       return this; // 把这个实例化对象接着返回
    }
}    
function $(...arg){
    
    
    return new 央央(...arg);
} 
//console.log($("button").eq(1));
// $("button").click(function(){
    
    
//     console.log(12);
// }).eq(0).click(function(){
    
    
//     console.log("这是0");
// });
console.log($("button").eq(0));
</script>    
</body>
</html>

返回上一次对象

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <meta http-equiv="X-UA-Compatible" content="ie=edge">
    <title>Document</title>
    <script src="js/Jquery.js"></script>
    <style>
        .active {
    
    
            background: red;
        }
    </style>
</head>
<body>
<a>链接</a>    
<button class="active">按钮1</button>
<button>按钮2</button>
<button>按钮3</button>
<button>按钮4</button>
<script>
// root 在操作当前次的时候,传入上一次的操作对象    
class 央央{
    
    
    constructor(arg,root){
    
    
        root = root||$(document,{
    
    });
        this["prevObject"] = root;// 把上一次的操作对象存入 this 的  prevObject 属性
        if(typeof arg === "string"){
    
     
            let ele = document.querySelectorAll(arg);
            this.setElement(ele);
        } else if(typeof arg === "object"){
    
     
            this.setElement(arg);
        } else if(typeof arg === "function"){
    
    
            window.addEventListener("DOMContentLoaded",arg);
        }
    }
    // 调用 end 方法,返回我们上一次的操作对象
    end(){
    
    
        return this["prevObject"];
    }
    eq(index){
    
    
        // 注意当用户调用 eq 方法之后,这会 操作对象会进行改变,返回把上一次的this 传入
        return $(this[index],this);
    }
    setElement(eles){
    
    
        if(eles.length === undefined){
    
    
            this[0] = eles;
            this.length = 1;
        } else {
    
    
            for(let i = 0; i < eles.length;i++){
    
    
                this[i] = eles[i];
            }
            this.length = eles.length;
        }
    }
    click(fn){
    
     
       for(let i = 0; i < this.length; i++){
    
    
            this[i].addEventListener("click",fn);
       }
       return this; 
    }
}    
function $(...arg){
    
    
    return new 央央(...arg);
} 
console.log($("button").eq(0).end());
</script>    
</body>
</html>

on 事件绑定

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <meta http-equiv="X-UA-Compatible" content="ie=edge">
    <title>Document</title>
    <script src="js/Jquery.js"></script>
    <style>
        .active {
    
    
            background: red;
        }
    </style>
</head>
<body>
<a>链接</a>    
<button class="active">按钮1</button>
<button>按钮2</button>
<button>按钮3</button>
<button>按钮4</button>
<script>
// root 在操作当前次的时候,传入上一次的操作对象    
class 央央{
    
    
    constructor(arg,root){
    
    
        root = root||$(document,{
    
    });
        this["prevObject"] = root;// 把上一次的操作对象存入 this 的  prevObject 属性
        if(typeof arg === "string"){
    
     
            let ele = document.querySelectorAll(arg);
            this.setElement(ele);
        } else if(typeof arg === "object"){
    
     
            this.setElement(arg);
        } else if(typeof arg === "function"){
    
    
            window.addEventListener("DOMContentLoaded",arg);
        }
    }
    // 调用 end 方法,返回我们上一次的操作对象
    end(){
    
    
        return this["prevObject"];
    }
    eq(index){
    
    
        // 注意当用户调用 eq 方法之后,这会 操作对象会进行改变,返回把上一次的this 传入
        return $(this[index],this);
    }
    setElement(eles){
    
    
        if(eles.length === undefined){
    
    
            this[0] = eles;
            this.length = 1;
        } else {
    
    
            for(let i = 0; i < eles.length;i++){
    
    
                this[i] = eles[i];
            }
            this.length = eles.length;
        }
    }
    click(fn){
    
     
       for(let i = 0; i < this.length; i++){
    
    
            this[i].addEventListener("click",fn);
       }
       return this; 
    }
    // 添加事件
    on(eventNames,fn){
    
    
        // eventNames eventNames 中可以存放多个 事件名称,每个事件名称中间用 空格 隔开
        eventNames = eventNames.trim().split(" ");
        eventNames = eventNames.filter(item=>item); // "" --> false 非空字符 true
        for(let i = 0; i < this.length; i++){
    
    
            for(let j = 0; j < eventNames.length; j++){
    
    
                this[i].addEventListener(eventNames[j],fn);
            }
       }
    }
}    
function $(...arg){
    
    
    return new 央央(...arg);
} 

$("button").on(" click  mouseout ",function(){
    
    
    console.log("11");
});
</script>    
</body>
</html>

css() 方法实现

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <meta http-equiv="X-UA-Compatible" content="ie=edge">
    <title>Document</title>
    <script src="js/Jquery.js"></script>
    <style>
        .active {
    
    
            background: red;
        }
        button {
    
    
            width: 55px;
        }
    </style>
</head>
<body>
<a id="a">链接</a>    
<button class="active">按钮1</button>
<button>按钮2</button>
<button>按钮3</button>
<button>按钮4</button>
<script>
// root 在操作当前次的时候,传入上一次的操作对象    
class 央央{
    
    
    constructor(arg,root){
    
    
        root = root||$(document,{
    
    });
        this["prevObject"] = root;// 把上一次的操作对象存入 this 的  prevObject 属性
        if(typeof arg === "string"){
    
     
            let ele = document.querySelectorAll(arg);
            this.setElement(ele);
        } else if(typeof arg === "object"){
    
     
            this.setElement(arg);
        } else if(typeof arg === "function"){
    
    
            window.addEventListener("DOMContentLoaded",arg);
        }
    }
    // 调用 end 方法,返回我们上一次的操作对象
    end(){
    
    
        return this["prevObject"];
    }
    eq(index){
    
    
        // 注意当用户调用 eq 方法之后,这会 操作对象会进行改变,返回把上一次的this 传入
        return $(this[index],this);
    }
    setElement(eles){
    
    
        if(eles.length === undefined){
    
    
            this[0] = eles;
            this.length = 1;
        } else {
    
    
            for(let i = 0; i < eles.length;i++){
    
    
                this[i] = eles[i];
            }
            this.length = eles.length;
        }
    }
    click(fn){
    
     
       for(let i = 0; i < this.length; i++){
    
    
            this[i].addEventListener("click",fn);
       }
       return this; 
    }

    // 添加事件
    on(eventNames,fn){
    
    
        eventNames = eventNames.trim().split(" ");
        eventNames = eventNames.filter(item=>item);
        for(let i = 0; i < this.length; i++){
    
    
            for(let j = 0; j < eventNames.length; j++){
    
    
                this[i].addEventListener(eventNames[j],fn);
            }
       }
    }

    // css 方法
    css(...arg){
    
    
        if(typeof arg[0] === "string"){
    
    
            if(arg.length > 1){
    
    
                // 两个参数 设置样式
                for(let i = 0; i < this.length; i++){
    
    
                   央央.setStyle(this[i],arg[0],arg[1]);
                }
            } else {
    
    
                // 一个参数获取样式
                return 央央.getStyle(this[0],arg[0]);
            }
        } else if(typeof arg[0] === "object"){
    
    
            // 批量设置样式
             //console.log(arg[0]);
             for(let i = 0; i < this.length; i++){
    
    
                 for(let s in arg[0]){
    
    
                    //console.log(s,arg[0][s]);
                    央央.setStyle(this[i],s,arg[0][s]);
                 }
             }
        }
        return this;//链式样式
    }
    static setStyle(el,attr,val){
    
    
        if(attr in $.cssHooks){
    
     // 如果 attr 这条是样式,用户设置 hooks,直接调用hooks把设置权交还给用户
            $.cssHooks[attr].set(el,val);
        } else {
    
    
            el.style[attr] = val;
        }
         
    }
    static getStyle(el,attr){
    
    
        return getComputedStyle(el)[attr];
    }
}    
function $(...arg){
    
    
    return new 央央(...arg);
} 
$.cssHooks = {
    
    
    width:{
    
    
        set(el,val){
    
     // 设置 width 时 会触发的方法
            //console.log(el,val);
            //console.log("准备开始设置width",val);
            el.style.transition = ".2s";
            el.style.width = val;
            setTimeout(()=>{
    
    
                el.style.transition = "none";
            },100);
            //console.log("已经设置了width",val);
        },
        get(){
    
    // 获取样式时会触发的方法
            return "获取时的值";
        }
    }
};



//$("button").css("width","100px");
//央央.setStyle(a,"color","red");
//console.log($("button").css("width"));
$("button").click(function(){
    
    
   // $(this).css("height","200px");
});

</script>    
</body>
</html>

csshooks 方法的实现

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <meta http-equiv="X-UA-Compatible" content="ie=edge">
    <title>Document</title>
    <script src="js/Jquery.js"></script>
    <style>
        .active {
    
    
            background: red;
        }
        button {
    
    
            width: 55px;
        }
    </style>
</head>
<body>
<a id="a">链接</a>    
<button class="active">按钮1</button>
<button>按钮2</button>
<button>按钮3</button>
<button>按钮4</button>
<script>
// root 在操作当前次的时候,传入上一次的操作对象    
class 央央{
    
    
    constructor(arg,root){
    
    
        root = root||$(document,{
    
    });
        this["prevObject"] = root;// 把上一次的操作对象存入 this 的  prevObject 属性
        if(typeof arg === "string"){
    
     
            let ele = document.querySelectorAll(arg);
            this.setElement(ele);
        } else if(typeof arg === "object"){
    
     
            this.setElement(arg);
        } else if(typeof arg === "function"){
    
    
            window.addEventListener("DOMContentLoaded",arg);
        }
    }
    // 调用 end 方法,返回我们上一次的操作对象
    end(){
    
    
        return this["prevObject"];
    }
    eq(index){
    
    
        // 注意当用户调用 eq 方法之后,这会 操作对象会进行改变,返回把上一次的this 传入
        return $(this[index],this);
    }
    setElement(eles){
    
    
        if(eles.length === undefined){
    
    
            this[0] = eles;
            this.length = 1;
        } else {
    
    
            for(let i = 0; i < eles.length;i++){
    
    
                this[i] = eles[i];
            }
            this.length = eles.length;
        }
    }
    click(fn){
    
     
       for(let i = 0; i < this.length; i++){
    
    
            this[i].addEventListener("click",fn);
       }
       return this; 
    }

    // 添加事件
    on(eventNames,fn){
    
    
        eventNames = eventNames.trim().split(" ");
        eventNames = eventNames.filter(item=>item);
        for(let i = 0; i < this.length; i++){
    
    
            for(let j = 0; j < eventNames.length; j++){
    
    
                this[i].addEventListener(eventNames[j],fn);
            }
       }
    }

    // css 方法
    css(...arg){
    
    
        if(typeof arg[0] === "string"){
    
    
            if(arg.length > 1){
    
    
                // 两个参数 设置样式
                for(let i = 0; i < this.length; i++){
    
    
                   央央.setStyle(this[i],arg[0],arg[1]);
                }
            } else {
    
    
                // 一个参数获取样式
                return 央央.getStyle(this[0],arg[0]);
            }
        } else if(typeof arg[0] === "object"){
    
    
            // 批量设置样式
             //console.log(arg[0]);
             for(let i = 0; i < this.length; i++){
    
    
                 for(let s in arg[0]){
    
    
                    //console.log(s,arg[0][s]);
                    央央.setStyle(this[i],s,arg[0][s]);
                 }
             }
        }
        return this;//链式样式
    }
    static setStyle(el,attr,val){
    
    
        if(attr in $.cssHooks){
    
     // 如果 attr 这条是样式,用户设置 hooks,直接调用hooks把设置权交还给用户
            $.cssHooks[attr].set(el,val);
        } else {
    
    
            el.style[attr] = val;
        }
         
    }
    static getStyle(el,attr){
    
    
        if(attr in $.cssHooks){
    
    
            return $.cssHooks[attr].get(el);
        }
        return getComputedStyle(el)[attr];
    }
}    
function $(...arg){
    
    
    return new 央央(...arg);
} 
$.cssHooks = {
    
    
    width:{
    
    
        set(el,val){
    
     
            el.style.width = val;
        },
        get(el){
    
    // 获取样式时会触发的方法
            return "就不告诉你";
        }
    }
};



//$("button").css("width","100px");
//央央.setStyle(a,"color","red");
//console.log($("button").css("width"));
$("button").click(function(){
    
    
   // $(this).css("height","200px");
   console.log($(this).css("width"));
});

</script>    
</body>
</html>

猜你喜欢

转载自blog.csdn.net/literarygirl/article/details/105894223