jQuery源码解析

作者: 犯迷糊的小羊 | 来源:发表于2016-11-16 22:33 被阅读411次

    自从学完JavaScript原生操作DOM的方法后有了一定基础后,就正式进入jQuery的学习;
    当学完jQuery的时候,回过头来才发现jQuery在操作DOm功能上的强大性;
    此时,在使用的过程中,不仅会对源码产生一定的好奇,相信各位童鞋也会有笔者这样一种体验,隐隐约约会写出类似这样的代码来:

    $('div').attr('titiel','javascript') ->
    var div = document.getElementsByTagName('div')[0];
    div.setAttribute('title','javascript')
    

    正所谓"前人栽树,后人乘凉。"jQuery的出现彻底解放了你记忆如此蛋疼的原生操作DOM的接口,jQuery面向用户良好的设计使得你在使用过程中就神不知给不觉的记忆住相应的API接口。
    作为一个求知欲稍微旺盛点的童鞋,可能会对jQuery的设计产生较为浓厚的兴趣,本文就旨在从宏观维度描述jQuery的基本框架以及介绍一些相对常用的api的知识点。jQuery版本为【jQuery.2.0.3】

    目录:

    1.jQuery的设计思想
    2.jQuery源码的基本框架
    1.jQuery的设计思想

    jQuery库在我看来核心就在query上,这个库初始设计出来就是为了方便DOM元素的选取,而后在jQuery对象上锁暴露出来的各种接口都是query的衍生。

    jQuery的设计思想可大致分为:

    • 选择网页元素
    • 改变结果集
    • 链式操作
    • 元素的操作:取值和赋值
    • 元素的操作:移动
    • 元素的操作:复制、删除和创建
    • 工具方法
    • 事件操作
    • 特殊效果

    1.选择网页元素
    对网页元素各种操作均是从选取该元素开始,将CSS选择器作为参数传入构造函数jQuery(简写为$)中,就可以选取到该元素

    $('docoment')//选取整个文档
    $('#id')//选取ID为id的元素
    ...
    

    2.改变结果集
    jQuery提供过滤器对上述选取的结果进行过滤以缩小选取范围;

    $('div').find('p')//选择div子元素为p的元素
    $('div').parent()//选择div元素的父元素
    $('div').children()//选择div的所有子元素
    $('div').siblings()//选择div的同级元素
    

    3.链式操作
    jQuery设计思想之三就是选中元素后可以对其进行一系列的操作,像链条形式一样

    $('div').find('p').css('color','red').html('hello world')
    

    4.元素的操作:取值和赋值
    jQuery可以使用同一个函数来完成取值和赋值操作

    $('div').html()//获取div元素里面的值
    $('div').attr('title','hello')//设置属性title的值为hello
    $('div').data('name')//获取div中name的数据值
    

    5.元素的操作:移动
    jQuery提供两组方法,来操作元素在网页中的位置移动。一组方法是直接移动该元素,另一组方法是移动其他元素,使得目标元素达到我们想要的位置,两种方法的区别在于第一个选取的jQuery对象不同。

    $('div').insertAfter('p')//将div元素移动到p元素后面
    $('p').after('div')//将p元素移动到div元素的前面
    
    $('div').append('p')//现存元素内部从后面插入元素
    $('p').appendTo('div')//将p元素插入现存元素div内部的后面
    

    6.元素的操作:复制、删除和创建

    $('div').clone()
    $('div').remove()
    $('div').empty()/清空元素内部的内容;
    $('<div>hello world</div>')//创建元素
    

    7.工具方法
    jQuery提供的工具方法是jQuery库的底层方法,在源码中jQuery对象的方法是基于工具方法,常见的工具方法有:

    $.makeArray()//将对象转换为数组;
    $.each()//遍历对象
    $.extend()//对象的合并
    

    8.事件操作
    将事件绑定到对象上去

    $('div').on('click',function(){})//添加点击事件
    $('div').one('click',function(){})//添加一次点击事件
    $('div').off('click',function(){})//移除事件
    
    $('div').on('click','ul',function(){})//事件代理
    

    9.特殊效果
    jQuery提供一些特效以供使用;

    $('div').show('slow')
    $('div').hide(2000)
    $('div').toggle()
    
    $('div').fadeIn()
    $('div').fadeOut()
    $('div').fadeToggle()
    
    $('div').slideUp()
    $('div').slideDown()
    $('div').slideToggle()
    
    $('div').animate({
      left:'20px'
    })
    
    $('div').stop()//停止特效执行
    
    2.jQuery源码的基本框架

    jQuery.2.0.3版本的代码的基本框架如下:

    (function(window,undefined){
      
      jQuery = function(selector,context){
        return new jQuery.fn.init(selector,context,rootjQuery)
      }
      
      jQuery.fn = jQuery.prototype{};
      jQuery.fn.init.prototype = jQuery.fn;
      
      jQuery.extend = jQuery.fn.extend = function(){}
      
      
      jQuery.extend({})
      
      jQuery.ready.promise = function(obj){}
      
      
      rootjQuery = jQuery(document)
      
      Sizzle:复杂选择器的实现
      
      
      //回调对象:对函数的统一管理
      jQuery.Callbacks = function(options){}
      
      //延迟对象:对异步的统一管理
      jQuery.extend({
        Deferred:function(){}
      })
      
      //功能检测
      jQuery.support = (function(support){})({});
      
      //数据缓存
      jQuery.extend({
        data:function(){},
        removeData:function(){}
      })
      jQuery.fn.extend({
        data:function(){},
        removeData:function(){}
      })
      
      //队列管理,对执行顺序的处理
      jQuery.extend({
        queue:function(){},
        dequeue:function(){}
      })
      jQuery.fn.extend({
        queue:function(){},
        dequeue:function(){},
        delay:function(){},
        clearQueue:function(){},
        promise:function(){}
      })
      
      //对元素属性的操作
      jQuery.fn.extend({
        attr:function(){},
        removeAttr:function(){},
        prop:function(){},
        removeProp:function(){},
        addClass:function(){},
        removeClass:function(){},
        toggleClass:function(){},
        hasClass:function(){},
        val:function(){},
      })
    
      //事件操作的相关方法
      jQuery.fn.extend({
        on:function(){},
        one:function(){},
        off:function(){},
        trigger:function(){},
        triggerHandler: function(){}
      })
      
      //DOM的操作
      jQuery.fn.extend({
        find:function(){},
        has:function(){},
        not:function(){},
        filter:function(){},
        is:function(){},
        closest:function(){},
        index:function(){},
        add:function(){},
        addBack:function(){}
      })
      jQuery.fn.extend({
        text:function(){},
        append:function(){},
        prepend:function(){},
        before:function(){},
        after:function(){},
        remove:function(){},
        empty:function(){},
        clone:function(){},
        html:function(){},
        replaceWith:function(){},
        detach:function(){}
      })
      
      //CSS样式操作
      jQuery.fn.extend({
        css:function(){},
        show:function(){},
        hide:function(){},
        toggle:function(){}
      })
     
      //事件绑定
      jQuery.fn.extend({
        hover:function(){},
        bind:function(){},
        unbind:function(){},
        delegate:function(){},
        undelegate:function(){}
      })
      
      //ajax操作
      
      //aniamate动画
      jQuery.fn.extend({
        fadeTo:function(){},
        animate:function(){},
        stop:function(){}
      })
      
      //位置与尺寸方法
      
      
      window.jQuery = window.$ = jQuery
      
    })(window,undefined);
    
    • 基本结构
    (function(window,undefined){
        jQuery = function(selector,context){
       return  new jQuery.fn.init(selector,context,rootjQuery) 
    }
      jQuery.fn = jQuery.prototype;
      jQuery.fn.init.prototoype = jQuery.fn;
      rootjQuery = jQuery(document)
      window.jQuery = window.$ = jQuery;
    })(window,undefined);
    

    1.jQuery库通过立即执行函数将整个代码封装在该作用域下;

    2.立即执行函数传递了window和undefined两个参数。传递window一方面有利于提高立即执行函数内部引用window对象的速度,另一方面是防止内部代码压缩时导致window对象被修改而出错;IE10以下,undefined可以被修改,为防止函数域内的undefined被修改,所以事先传参;强力推荐老司机写的文章【var undefined = 1 这样赋值有效果吗】

    3.上述代码的核心是定义一个jQuery的函数,这个函数返回值为jQuery原型对象下init属性的构造函数,因此当我们每次使用jQuery.('div')返回的就是一个jQuery对象,该对象由构造函数jQuery.fn.init创建的;

    jQuery  = function(selector,context){
        return new jQuery.fn.init(selector,context,rootjQuery)
    }
    jQuery.fn = jQuery.prototype;
    jQuery.fn.init.prototoype = jQuery.fn;
    rootjQuery = jQuery(document)
    window.jQuery = window.$ = jQuery;
    

    window.jQuery = window.$.jQuery使得我们可以在全局下使用$()jQuery()的效果是一样的;
    jQuery.fn = jQuery.prototype意思是jQuery原型对象可以使用jQuery.fn方式简写;
    ·jQuery.fn.init.prototoype = jQuery.fn意思是构造函数jQuery.fn.init的原型对象就是jQuery.fn;

    基本结构部分大致描述的jQuery整体设计的框架。

    3.jQuery源码各部分的脑图

    jQuery源码解析.png

    【注】
    Sizzle:复杂选择器的实现
    这部分代码本身就是可以作为独立的Sizzle.js库,专门通过复杂选择器获取元素

    相关文章

      网友评论

      本文标题:jQuery源码解析

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