JQ原理

作者: 追梦灬且随风前行 | 来源:发表于2017-08-26 16:24 被阅读0次

    jq的基本结构

    1、闭包的形式。不与外界框架冲突,把私有变量赋值给了全局变量 windows
    2、一个工厂函数,函数返回的是一个构造函数的实例化对象
    3、通过原型式继承,将工厂函数的原型对象 赋值给 构造函数的原型对象;便可以访问工厂函数里面的方法。
    4、ready方法。封装监听了dom加载完毕,再回调函数,监听要兼容ie5(attachEvent)  谷歌addEventListener
    5、封装了插件一些工具方法(插件)比如:isString; trim; isLikeArray 封装在jq的扩展方法extend上,也就是jq的静态方法上,在通过拷贝给this,$.isString()访问
    6、入口函数分析:①判断是够为false 返回一个空的实例化对象
    ②、是否为函数、调用this.ready()
    ③、字符串
      1、是否是html,将一级标签一次key-value保存到实例化对象。
          var oDiv = document.createElement("div");
         oDiv.innerHTML = selector;
        [].push.apply(this, oDiv.children);
      2 判断是否是选择器。 [].push.apply(this, document.querySelectorAll(selector));
    获取页面中所有指定的标签 + 把所有的标签都保存到实例对象中 + 添加length属性3、数组和伪数组
    
       
    8、有一些方法each。map不仅在扩展方法(工厂函数的静态方法),在原型对象也封装了。$.each(参数1,函数) ,  $().each(函数)
      //具体实现:先遍历temp,然后把key-value传递给fn (遍历需要判断是否是数组,伪数组,对象)  在赋值key-value 并且this改变指向value
        for (var i = 0; i < temp.length; i++) {
                      var res = fn.call(temp[i],i,temp[i]);
                        if(res == false) break; }
    9、一些原型对象方法是get、eq、first、last
      get获取的是没有解析的dom元素、而eq方法获取是dom里内容 只需要this.get(idnex)  相当于$(代码片段)
      get:function (index) {
                /*
            参数:正数(0|1|2) 表示获取key为0.1.2.对应的DOM元素
                 负数(-1) 表示获取最后一个元素
                 如果不传递参数,那么把所有的标签都放在数组中返回 (实例对象 -> 数组)
                * */
                //001 判断没有参数的情况
                if(arguments.length == 0)
                {
                    return this.toArray();
                }else if(index >=0)
                {
                    return this[index];
                }else if(index < 0)
                {
                    //负数:
                    //length 6
                    //-1 倒数第一个  5  == length + (-1)
                    //-2 倒数第二个  4  == length + (-2)
                    return this[this.length + index];
                }
            },
    
    10、代码的可读性,一些方法封装在工产函数的扩展属性html,text,remove,empty
     text:(innerText)
            001 没有参数:把所有选中的标签的innerText属性的值拼接成字符串返回
            002 传递参数(字符串|代码片段):把传入的参数作为innerText的属性值保存
    
    11、操作一些属性节点,和属性
    attr:设置(获取|修改和添加)属性节点
        //01 如果不传递参数,直接报错
        //02 传递1个参数(字符串):把指定的所有标签中的第一个标签中指定的属性节点对应的值返回 (getAttribute)
     //03 传递1个参数(对象):批量的设置(添加|修改)对象的属性节点
      //04 传递2个参数:相当于给所有选中的标签都添加属性节点,第一个参数是属性节点的名称,第二个参数是属性节点对应的值
    removeAttr:删除属性节点  . removeAttribute删除属性节点
     //01 如果没有传递参数:返回实例化对象
     //判断是否有参数,如果传递了参数,那么就把所有标签中的属性节点删除
    prop:设置(获取|修改和添加)属性   this.name=value添加
    removePorp:删除属性     delete删除属性
    
    12. css操作
    
    01 jQuery基本结构:闭包(立即调用函数)
    02 为什么要使用闭包? => 闭包的好处:为了避免和其他的框架产生冲突
    03闭包的结构:
       函数的参数:形式参数 + 实际参数
       函数的调用:实际参数的值赋值给形参
       形式参数:window | undefined (本质上就是在函数内部声明一个临时的变量)
       实际参数:window
       window参数:
        (1) 方便代码压缩,压缩后的 window---> a
        (2) 提升性能(缩短查找链,能快速的访问window)
       undefined参数:
        (1) 方便代码压缩
        (2) 处理兼容性问题(老版本的浏览器|IE) 因此增加一个形参undefined
            001 在IE9-之前undefined可以被修改
            002 在IE5之前undefined不可以直接使用
    04外部为什么可以访问$或者是jQuery?
        基本结构是立即调用函数,正常情况下函数外部无法访问函数内部的私有变量
        (1) 闭包,返回函数,在该函数中间接的访问私有数据
        (2) 把私有的数据绑定给全局的变量(jQuery)
         window.$ = window.XMGQuery = XMGQuery;
    
    

    jq入口函数分析

    //001 条件判断为false
        //比如:"" undefined null 0 false NaN等等
        //结果:空的jQuery实例对象  init{ };
    
    002 字符串 (选择器)
    比如: $('div')等;
    返回的是一个伪数组; {0:div,1:div,2:div....num-1:div,length:num}
    
     003 字符串(代码片段)
    $("<div>我是div</div>")
    $("<div>我是div<strong>I am strong</strong></div><span>我是span</span>")
    结果:把代码片段中所有的一级标签依次作为key为0.1.2.3..对应的value保存到实例对象中返回    {0:div,length:1 }  {0:div.1:span,length:2}
    
    004数组
    $(["demo01", "demo02", "demo03"])
    结果;把数组中每个元素依次取出来,作为key为0.1.2.3..对应的value值保存到实例对象中返回  {0:demo01,1:demo02,2:demo03,length:3}
    
    005伪数组
    $({0:"name",1:"age",2:"color",length:3});
    结果;把数组中每个元素依次取出来,作为key为0.1.2.3..对应的value值保存到实例对象中返回 {{0:"name",1:"age",2:"color",length:3}
    
    006 Dom对象
     var oDiv = document.createElement("div");
    $(oDiv)
    结果:返回的是一个伪数组 {0:div,length :1}
    
    007对象
      var obj = {name:"张三"};
        console.log($(obj));
    结果返回一个伪数组;对象的内容保存在  {0:Object, length:1}
    
    008 非0的数字 或者true
    $(123);  $(true)
    结果:也是一个伪数组
    {0:123,length:1}   {0:true,length:1}
    
    009 函数
    基本用法
    $(function(){});
    $().ready(function(){})         作用:等页面加载完毕后,再执行回调函数
    等价于 window.onload=function(){}
    

    常用的jq方法

      1、条件判断为false的情况  " ",underfined, null,0,NAN
        返回一个空的对象 init{ } 
    
      2、 字符串(代码片段)
    $("<div>我是div</div>")
    $("<div>我是div<strong>I am strong</strong></div><span>我是span</span>")
    结果:把代码片段中所有的一级标签依次作为key为0.1.2.3..对应的value保存到实例对象中返回    {0:div,length:1 }  {0:div.1:span,length:2}
    
      3、选择器 
     $('div') == 返回伪数组
        {0:div,1:div,2:div....num-1:div,length:num}
    
    cal和applyl方法的介绍
    call和apply
    作用:
        借用其他对象的方法,并且绑定函数内部this
        对象1.方法.call(对象2)
        对象1.方法.apply(对象2)
    区别:
          001 传递参数不一样
              对象1.方法.call(对象2,参数1,参数2....)
              对象1.方法.apply(对象2,[参数1,参数2....])
          002 length不一样
              call.length :1
             apply.length:2
    
    4.trim方法
    作用:清除字符串前面和后面的空格
    注意点:兼容性问题(先判断当前环境是否支持,如果不支持那么自定义)
    
    js:var str02 = " abc";      
        console.log(str02.trim()); == ‘abc’
    jq:var content = $('#content').val();
        jQuery.trim(content)
    
    工具方法处理;
    处理思路:
        把工具方法写在jQuery自己身上或者是写在jQuery的实例对象的原型对象上面
        如果写在jQuery函数身上,那么在调用的时候,应该$.工具方法(建议)
        如果写在jQuery实例对象的原型对象上面,那么应该$().工具方法
    
    建议:通常来说工具方法是不依赖实例对象的,因此建议把工具方法写在函数身上
    
    原型对象上面的属性和方法:
        jquery:版本号
        selector:默认的选择器
        length:默认的长度
        toArray():把实例对象转换数组返回
        get():获取指定下标的元素,获取的是原生DOM
              参数:正数(0|1|2) 表示获取key为0.1.2.对应的DOM元素
                   负数(-1) 表示获取最后一个元素  $('div').get(-1)
                   如果不传递参数,那么把所有的标签都放在数组中返回
    
        eq():获取指定下标的元素,把该元素保存到实例对象中返回
              参数:正数(0|1|2) 表示获取key为0.1.2.对应的DOM元素,保存到实例对象中
                负数(-1) 表示获取最后一个元素,保存到实例对象中
                如果不传递参数,返回的是一个空的对象(并不是实例对象本身)
          $('div').eq(-1)  --> {0:div,length:1}
    
         first:获取指定标签中的第一个DOM元素,并且把该元素保存到实例对象中返回
        last:获取指定标签中的最后一个DOM元素,并且把该元素保存到实例对象中返回
        $("div").first() ==  $('div').eq(0)   结果 {0:div,length:1}
    
    push: 给数组添加元素,返回数组得到长度
    sort: 返回一个空数组
    $().push(1, 3, "demo", "test","abc")  ==  5  = [].push
    $().sort(1, 3, "demo", "test","abc")  ==  { }
    
    each
    使用方法:
        (1) $().each(function () {})   原型方法
        (2) $.each(obj,function (){}) 静态方法
    功能:
        (1) 遍历对象|数组|伪数组,把对象的key-value传递给回调函数
        (2) 终止遍历过程
    注意点:
        在回调函数中this并不是指向window,而是指向value的值
        为什么要设置this指向value:因为在回调中我们使用最多的就是value的值,this方便操作
        解决方法:绑定回调函数this - >value (call|apply)
    
    map
    使用方法:
        (1) $().map(function () {})   原型方法
        (2) $.map(obj,function (){})  静态方法
    功能:
        (1) 遍历对象|数组|伪数组,把对象的key-value传递给回调函数(key-value相反)
        (2) 不能终止遍历过程
        (3) 能够收集回调函数中的返回值,组织成一个新的数组返回
        (4) this指向的是window
    
    empty   清空标签的内容,返回标签清空的伪数组  $('div').empty()  ;  {0:div,1:div:length: 2}  
    remove: 清除标签; 返回underfined
     html() 和 text() ;
    $("div").html("<div>我是很好的div</div>")div里的内容为 “<div>我是很好的div</div>“” 不能解析标签
    $("div").text("<div>我是很好的div</div>")  div里的内容为 “”我是很好的“”
    
    操作CSS的方法
    attr:设置(获取|修改和添加)属性节点
     //01 如果不传递参数,直接报错
        //console.log($("div").attr());
     //02 传递1个参数(字符串):把指定的所有标签中的第一个标签中指定的属性节点对应的值返回
        console.log($("div").attr("color")); //red
    03 传递1个参数(对象):批量的设置(添加|修改)对象的属性节点
        console.log($("div").attr({
            age:"100",
            type:"typeTest",
            color:"yellow"
        }));
     //补充:如果传递一个参数,这个参数既不是字符串也不是对象那么就报错
    04 传递2个参数:相当于给所有选中的标签都添加属性节点,第一个参数是属性节点的名称,第二个参数是属性节点对应的值
        console.log($("div").attr("age", "123"));
    
    removeAttr:删除属性节点
     //01 如果没有传递参数:返回实例化对象
        //console.log($("div").removeAttr());
        //02 传递一个参数:删除所有标签中指定的属性节点
        console.log($("div").removeAttr("color"));
    
    prop:设置(获取|修改和添加)属性
      属性和属性节点的区别:
    属性|属性节点
    属性:对象都有属性,直接保存在对象身上 {age:23}
    属性节点:DOM元素才有属性节点,保存在attributes属性上 <div color=red></div>
    
    //00 添加属性
        var ds = document.querySelectorAll("div");
        ds[0]["test"] = "testDemo1";
        ds[1]["test"] = "testDemo2";
        //01 不传递参数:直接报错
        $("div").prop();
        //02 传递1参数(字符串):把指定的所有标签中的第一个标签中指定的属性对应的值返回
        console.log($("div").prop("color"));
        //03 传递1个参数(对象):批量的设置(添加|修改)对象的属性
        console.log($("div").prop({
            "test1":"testA",
            "test2":"testB"
        }));
        //04 传递2个参数
        console.log($("div").prop("test3","texstC"));
    
    
    removePorp:删除属性
     //01 如果没有传递参数:返回实例化对象
        //console.log($("div").removeProp());
        //02 传递一个参数:删除所有标签中指定的属性
        console.log($("div").removeProp("test"));
    
    val:获取value的值
     //01 如果没有传递参数,那么表示获取第一个标签中的value
            //console.log($("input").val());
    
            //02 传递参数:修改所有标签的value
            console.log($("input").val("李四"));
    
            //补充(注意点):DOM对象中有两个value
            //(1)value属性节点
            //(2)value属性     实时更新
    
    css:设置样式
    hasClass:是否有class
     //00 如果不传递参数,总是返回false
        //console.log($("div").hasClass());
        //01 传入参数
        //判断页面中所有的div标签中是否存在a这个class
        //如果有,那么就返回true,如果没有那么就返回false,只要有那么就返回true
    //    console.log($("div").hasClass("aabbc"));
    
    addClass:添加class
    removeClass:删除class
    toggleClass:切换(如果有那么就删除,如果没有那么就添加)
    

    JQ 工具方法

    一些工具方法储存在jq的实例对象中,还有的储存在jq原型对象init函数的实例对象中$().,前面时候 $后面不需要加()
    
    例如:$.isString('123') = true 
    常见的JQ静态方法工具方法有 $.isString()
    isString 判断是否是字符串  
    isHtml 判断是否为html标签
    trim 去除空格 $.trim('   12')
    isArray 判断是否是数组
    isLikeArray  判断是否是伪数组
    isObject   判断是否是对象
    isWindow  判断是否是window的对象
    isFunction 判断是否是函数
    each 遍历对象 、数组  $.each(obj,function(index.item){  } )
    map 遍历对象 、数组 $.map(obj,function(item.index){  } )
    
    常见的jq原型对象的静态方法 $().empty()
    empty
    remove
    text
    html
    appendTo
    prependTo
    append
    prepend
    

    相关文章

      网友评论

          本文标题:JQ原理

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