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>
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章