美文网首页
自定义封装一个简易jQuery

自定义封装一个简易jQuery

作者: 小宇cool | 来源:发表于2020-06-01 14:38 被阅读0次

jQuery实质为构造函数,这个构造函数接受一个参数,jQuery内部通过这个参数利用原生的API找到相对应的DOM节点,然后把节点挂载到实例的jQuery对象上,给这个构造函数的原型上添加了许多方法,方法实例对象JQuery对象调用.

1.模拟实现简易的jQuery

我们可以通过自执行函数,在函数内部创建一个jQuery对象,这个对象接受一个参数为,返回一个实例化的jquer对象

jQuery是一个典型的工厂模式,你给它一个什么参数,它返回给你符合参数要求的DOM元素.

jQuery,内部帮我们调用了new, 让我们调用更加方便.

1.1 搭建基本结构
(function (){
let jQuery = function(selector){
    // 内部手动调用new,  返回实例对象
    return new jQuery.fn.init(selector)// new一下init, init 才是真正的构造函数
}
//jQuery.prototype的简写方式
jQuery.fn = jQuery.prototype;
jQuery.fn.init = function(selector){   }//这里面实现真正的构造函数
//让init和jQuery的原型指向同一个对象, 便于挂载实例方法
jQuery.fn.init.prototype = jQuery.fn;  
//最后把jQuery挂载到window上. 方便调用
 window.$ = window.jQuery = jQuery   
})()

1.2 实现构造函数
 jQuery.fn.init = function (selector) {
     //我们对用户传入的参数进行判断, 如果传入的参数包含,就通过类名获取DOM元素
     if(selector.tagName){// 如果传入的参是一个原生的DOM元素, 那么它对应的标签名一定有值
         this[0] = selector;
         this.length = 1;
         return //此时应该打断函数执行, 避免发生错误
     }
     if (selector.includes(".")) {
         let name = selector.slice(1);//截取类名
         // 原生的HTMLcollection集合,不方便我们循环, 我们通过Array.from把他转为数组
         let DOMList = Array.from(document.getElementsByClassName(name));
         //遍历这个DOM列表, 给实例化的jQuery对象通过键值对添加相应的DOM元素
         for (let [key, item] of DOMList.entries()) {
             this[key] = item;
         }
         //给实例化对象添加一个length属性, 记录DOM元素的个数
         this.length = DOMList.length
     } 
    }

在控制台输入console.log($(".item")), 打印成功,说明构造函数没问题.


image-20200601121939822.png
1.3 封装获取实例化对象DOM元素函数

获取实例化对象的所有DOM元素,方便我们将来给构造函数的原型挂载方法时,调用需要的DOM元素.

 //封装获取原生dom对象数组的函数
     function getDom(obj){
        let DOMlist = [],
            length = obj.length;//获取length属性 控制循环的次数
        for(let i = 0; i < length; i++){
            DOMlist.push(obj[i])//往要返回的数组添加节点
        }
         //返回DOM节点列表
        return DOMlist
     }
1.4 click方法

我们模拟一下jQuery的click方法,

首先我们接受一个回调函数,重点我们要把将回调函数的内部this绑定到相对应的DOM节点.

//给构造函数原型添加click方法 这个方法接受一个回调函数
 jQuery.fn.click = function(callback){
    //判断一下传入的参数类型是否为函数 如果不是就抛出一个错误
     if(typeof callback !== "function"){
         throw new  Error("The argument should be a function");
         return
     }
     //获取DOM元素列表
     let DOMList = getDom(this);
     //然后我们用原生的事件监听给每个DOM元素绑定点击事件
     for(let [key,item] of DOMList.entries()){
         item.addEventListener("click",function(ev){
            //接着我们通过call将回调函数的内部this指向相对应的this节点,传入一个ev事件对象
            callback.call(this,ev)
        })
     }
     //返回实例对象,方便我们链式调用
     return this
 }
 }
1.5 css方法

我们这里简单模拟一下设置单个css属性值, 首先这个方法一个接受两个参数,第一个参数为属性值名 第二个为属性值

 jQuery.fn.css = function(name,value){
        //判断一下参数类型是否正确 
     if(typeof name !== "string" && value  !== "object" ){
         throw new Error("The argument should be a string ")
         return
     }
     //获取DOM列表
     let DOMList = getDom(this);
     //循环设置css属性值
     DOMList.forEach((item)=>{
         item.style.cssText = `${name}:${value}`
     })
     return this
    }


1.6 each方法

回调函数接受两个参数,第一个为下标, 第二个为对应的DOM元素,


jQuery.fn.each = function(fn){
    let result = getDom(this);
    for(let [key,val] of result.entries()){
        fn.call(null,key,val)//如果call 给回调函数传入index和item
    }
    return this
}
1.7 简单的测试案例
<!DOCTYPE html>
<html lang="en">

<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Document</title>
</head>
<body>
    <button class="item">按钮1</button>
    <button class="item">按钮2</button>
    <button class="item">按钮3</button>
    <button class="item">按钮4</button>
    <button class="item">按钮5</button>
</body>
</script>
<!-- 引入我们写好的js文件 -->
<script src="./jquey.js"></script>
<script>
//给所有的按钮绑定点击事件,每次只给当前点击的元素添加颜色
    $(".item").click(function (ev) {
        $(".item").each((index, item) => {
            $(item).css("color", "")//清空之前设置的字体颜色
        });
        $(this).css("color", "red")//给当前点击的元素添加字体颜色
    });
</script>
</html>

ok到这里就差不多,这里实现的都是一些很基本的功能, 可能不是很完美.但可以拿来娱乐娱乐.我觉得学习不仅要知其然, 也要知其所以然.我们不仅会用轮子,也要了解一点怎么造轮子.这样我们的个人水平可以更进一步,将来选择的权利就会更多.
.

相关文章

网友评论

      本文标题:自定义封装一个简易jQuery

      本文链接:https://www.haomeiwen.com/subject/vetszhtx.html