周末没事自己撸一个简易的Jquery库吧

770 阅读2分钟

周末没事自己撸一个简易的Jquery库吧

说到JQuery,相信大家肯定很不陌生,很多人都将Jquery归为JS框架一类,其实Jquery是属于库,所谓的JS库就是用原生的JS作为底层去构建的,其中并没有其他第三方库的依赖,有的人说都什么时代了还说JQuery,俗话说的好:“不忘初心,成事之根本”,JQuery也是当初非常火的一个库,对于某些公司来说现在的技术栈中还是存在着Jquery。于是自己在年后决定看一下Jquery源码,并打算自己简单实现一下。那废话不多说,现在开始!

为什么要使用jQuery

  • 可通过任意(css选择器)来查询文档元素
  • 简洁的语法,比原生JS更简便的操作选中的元素

开始实现之前需要明确

  • 自己必须得会用Jquery,必须熟悉Jquery的方法使用,文档戳这里Jquery中文文档
  • jQuery定义了一个全局函数,该函数使用频繁,那就给它改名为 , ,() 的返回值是一个jQuery对象 , 这里要注意它与JavaScript直接获取 dom 是不同的; jQuery获取DOM只能用jQuery的方法来操作DOM,JavaScript同理,两者不能互相调用和使用披此的方法。
  • 在jQuery类库中,最重要的方法是jQuery()方法 (也就是 $()) , 它的功能也是非常的强大的,下面给大家介绍集中在使用jQuery常用的调用方式
    // 1. 传入css 选择器
    $('在这里填入css选择器') 
    // 2. 传入document,window
    $(document)
    // 3. 传入函数
    $(function(){
            // 需要执行的内容
    })
    // 其实$() 还支持 第二个参数,这里就不过多解释了,感兴趣的可以去看官方文档    
    
  • 简单实现jQuery调用方式,以及其他操作DOM的功能
    // 首先创建一个构造函数
        var jQuery = function(selector,context){
                    this.prevObject = context ? context:[document];
                    this.init(selector)   
        } 
    //初始化状态 分两种传参情况
        jQuery.prototype.init=function(selector){
                        //1. css 选择器
                        if(typeof selector==='string'){
                            [...document.querySelectorAll(selector)].forEach((item,index)=>{
                                    this[index]=item;
                            }); 
                        //2. 传入函数    
                        }else if(typeof selector==='function'){
                            document.addEventListener('DOMContentLoaded',selector);     
                        }
                        //因为上面 $(document) 调用方法与$(funciton(){})执行效果一样,所以这里值实现后面的     
        }  
    

上面的调用方法基本就实现了,那我们就简单实现一下其他的方法吧)

  • eq() 方法的实现

     jQuery.prototype.eq=function(index){
                  index = index?index:0;
                  return new jQuery(this[index],this); //将当前装,第一状态返回为了使用后end()方法
     },
    
  • end() 方法的实现

    //获取第一状态
    jQuery.prototype.end=function(){
                    return this.prevObject;
        },
    
  • css() 方法的实现

     jQuery.prototype.css=function(...style){
         // style 传参需要考虑两种形式 第一种css("color","red")  第二种就是以对象的形式传递了 
                   if(!this[0]){
                       return this;
                   }
                   if(typeof(style[0])!=='object'){   
                     //通过属性Object.keys(this)索引改变样式
                     Object.keys(this).forEach((item,index)=>{
                        if(typeof (parseInt(item))=='number'&& !isNaN(parseInt(item))){
                          this.setStyle(this[item],style[0],style[1]);
                         }
                     })
                   }else{
                     
                     Object.keys(this).forEach((item,index)=>{
                        if(typeof (parseInt(item))=='number'&& !isNaN(parseInt(item))){
                            for(let name in style[0]){
                                this.setStyle(this[item],name,style[0][name])
                            }
                        } 
                         
                     })  
                   }
                   return this; 
             },
             //setStyle 函数 来改变元素的样式
             setStyle:function(ele,name,value){
                  
                     ele.style[name]=value;
             },
    
  • removeClass() 方法的实现

    //  removeClass 方法的实现实现就简单很多了,包括 addclass,toggleClass 方法就不去实现了原理与removeClass类似
        jQuery.prototype.removeClass=function(className){
                        Object.keys(this).forEach((item,index)=>{
                            if(typeof (parseInt(item))=='number'&& !isNaN(parseInt(item))){
                                this[item].classList.remove(className);
                            } 
                            
                        })
                        return new jQuery(this,this)
                    },
    
  • on(事件名,回调函数)

    jQuery.prototype.on=function(eventNames,fn){
                    //这里需要考虑eventNames 参数不一定是字符串 还可能是数组
                    let events = eventNames.split(" ");
                    Object.keys(this).forEach((item,index)=>{
                        if(typeof (parseInt(item))=='number'&& !isNaN(parseInt(item))){
                            events.forEach(e=>this[item].addEventListener(e,fn));
                        }   
                    }) 
                    return this; 
                }
    
  • 最后就Ajax了,让我们的看看Jquery的Ajax是如何封装的

    //这里Ajax与Jquery的源码一样都是在创建实例之后加入Ajax方法的,其实我实现也很简单就是使用元素JavaScript封装Ajax之后添加到实例上就可以了;
    window.jQuery = window.$ = function(selector,context){
            return new jQuery(selector,context);
        };
        $.ajax=function(options){
            
            var type,params,xhr; // 请求类型,传参,http实例  
            options = options || {};
            type = (options.type||'GET').toUpperCase(),
            params = formsParams(options.data);
            //  创建实例
            if(window.XMLHttpRequest){
                xhr=new XMLHttpRequest();
            }else if(window.ActiveObject){//兼容IE6以下版本
                xhr=new ActiveXobject('Microsoft.XMLHTTP');
            }
            //发送请求 GET/POST
        
            if(type=='GET'){
                xhr.open("get",options.url + "?" + params,true);
                xhr.setRequestHeader(options.headers||"Content-Type", "application/json;charset=utf-8");
                xhr.send();
            }else if(type=="POST"){
                xhr.open("post",options.url,true);
                xhr.setRequestHeader("Content-Type", "application/x-www-form-urlencoded");
                xhr.send(params);
            }
            // 可以自己拓展 put
            //设置超时时间
            setTimeout(function(){
                if(xhr.readySate!=4){
                    xhr.abort();
                }
            },options.timeout||2000);
            xhr.onreadystatechange = function(){
                if(xhr.readySate=4&&xhr.status==200){
                        options.success(xhr.responseText);
                }else{
                        options.error(xhr.status);
                }
            }
        };
        // 格式化数据格式的
        function formsParams(data){
            var arr = [];
            for(let key in data){
                arr.push(key+'='+data[key]) 
            }
            return arr.join('&');
        }
    

整体就实现这么多,感兴趣的朋友可以自己去看一下JQuery,并继续再此基础上完善。

  • 下面使用我们刚刚封装的Jquery来做一个轮播图
    <!DOCTYPE html>
    <html lang="en">
    <head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Document</title>
    <script src="./JQE.js"></script>
    </head>
    <style>
       .dome{
             width:300px;
             height: 200px;
             display: flex;
             flex-direction: row;
    
             background: red;
    
       }
       .dome .swiper{
              flex: 1;
              position: relative;
       } 
       .dome .swiper .imgs{
            width: 100%;
            position: absolute;
            top: 0;
            left: 0;
            display: none;
       }
       .btn{
           cursor: pointer;
       }
    </style>
    <body>
    <div class="dome">
           <div class=" btn pre">《</div>
           <div class="swiper">
                <img class="imgs" src="https://p3-juejin.byteimg.com/tos-cn-i-k3u1fbpfcp/951ee8139e244bb1a7e3aa33fb7838e2~tplv-k3u1fbpfcp-zoom-1.image" alt="">
                <img class="imgs" src="https://p3-juejin.byteimg.com/tos-cn-i-k3u1fbpfcp/4e267239cd1a48bc83cdf1c9d88dec49~tplv-k3u1fbpfcp-zoom-1.image" alt="">
                <img class="imgs" src="https://p3-juejin.byteimg.com/tos-cn-i-k3u1fbpfcp/a0216e5f6bf04b5f9ba0ee0a81a7be06~tplv-k3u1fbpfcp-zoom-1.image" alt=""> 
           </div>
           <div class=" btn next">》</div>
    </div>
    
    </body>
    <script>
    
    
       $(function(){
             var num = 0;
             $('.pre').on('click',function(){
                move(-1)
             })
             $('.next').on('click',function(){
                move(1)
             })
             $('.imgs').eq(0).css("display","block");
             function move(dot){
                    num+=1*dot; 
                    num = num>$('.imgs').length()-1?0:num;
                    num = num<0?$('.imgs').length()-1:num;
                    console.log(num)
                    $('.imgs').eq(num).css("display","block").siblings('.imgs').css("display","none")
    
             } 
    
       })
    </script>
    </html>
    //是不是用jQuery写轮播图很简单啊 
    
    

总结

个人认为JQuery主要使用的还是是链式操作,JS中10行代码能做的有可能在Jquery中只用1-2行就能解决,看过源码之后,自己也学到了不少东西,比如Jquery的链式操作,还有设计模式等等,强烈简易,前端进阶的朋友去挑战一下。不单单是学习,也是对自己JS能力的一种锻炼, 看到这里,关于本篇内容就到最后了,文章如有不足之处还请留言反馈,感谢支持。