(96, 283)给JQ对象,添加一些属性和方法

简化代码结构

  • jQuery的初始化
    jQuery = function( selector, context ) {
      // The jQuery object is actually just the init constructor 'enhanced'
      return new jQuery.fn.init( selector, context, rootjQuery );
    }
    
  • jQuery对象的属性和方法
    jQuery.fn = jQuery,prototype = {
      jquery: 版本
      constructor: 修正指向问题
      init(): 初始化和参数管理
      selector: 存储选择字符串
      length: this对象的长度
      toArray(): 转数组
      get(): 转原生集合
      pushStack(): JQ对象的入栈
      each(): 遍历集合
      ready(): DOM加载的接口
      slice(): 集合的截取
      first(): 集合的第一项
      last(): 集合的最后一项
      eq(): 集合的指定项
      map(): 返回新集合
      end(): 返回集合前一个状态
      push(): (内部使用)
      sort(): (内部使用)
      splice(): (内部使用)
    }
    
  • 更改init的原型
    jQuery.fn.init.prototype = jQuery.fn;
    

jQuery对象的属性和方法详解

jQuery: core_version
core_version = "2.0.3",
// 2.0.3
$().jquery;
constructor: jQuery 修正指向问题
// 在js源码当中
// Aaa.prototype.constructor = Aaa;
// 所以当prototype.constructor是在创建的时候就设置好的
function Aaa(){

}

var a1 = new Aaa();
// 输出
/*
function Aaa(){

}
*/
alert(a1.constructor);

// ———————————————————————————————————————————
// 有下面两种写法
// 第一种
// 不会改变constructor
Aaa.prototype.name = 'hello';
Aaa.prototype.age = 30;

// 第二种
// 会改变constructor 为Object
Aaa.prototype = {
  // 添加
  constructor: Aaa,
  name: 'hello',
  age: 30
}
初始化函数init
  • 源码:
    init: function( selector, context, rootjQuery ) {
      var match, elem;
    
      // HANDLE: $(""), $(null), $(undefined), $(false)
      if ( !selector ) {
        return this;
      }
    
      // Handle HTML strings
      if ( typeof selector === "string" ) {
        if ( selector.charAt(0) === "<" && selector.charAt( selector.length - 1 ) === ">" && selector.length >= 3 ) {
          // Assume that strings that start and end with <> are HTML and skip the regex check
          match = [ null, selector, null ];
    
        } else {
          match = rquickExpr.exec( selector );
        }
    
        // Match html or make sure no context is specified for #id
        if ( match && (match[1] || !context) ) {
    
          // HANDLE: $(html) -> $(array)
          if ( match[1] ) {
            context = context instanceof jQuery ? context[0] : context;
    
            // scripts is true for back-compat
            jQuery.merge( this, jQuery.parseHTML(
              match[1],
              context && context.nodeType ? context.ownerDocument || context : document,
              true
            ) );
    
            // HANDLE: $(html, props)
            if ( rsingleTag.test( match[1] ) && jQuery.isPlainObject( context ) ) {
              for ( match in context ) {
                // Properties of context are called as methods if possible
                if ( jQuery.isFunction( this[ match ] ) ) {
                  this[ match ]( context[ match ] );
    
                // ...and otherwise set as attributes
                } else {
                  this.attr( match, context[ match ] );
                }
              }
            }
    
            return this;
    
          // HANDLE: $(#id)
          } else {
            elem = document.getElementById( match[2] );
    
            // Check parentNode to catch when Blackberry 4.6 returns
            // nodes that are no longer in the document #6963
            if ( elem && elem.parentNode ) {
              // Inject the element directly into the jQuery object
              this.length = 1;
              this[0] = elem;
            }
    
            this.context = document;
            this.selector = selector;
            return this;
          }
    
        // HANDLE: $(expr, $(...))
        } else if ( !context || context.jquery ) {
          return ( context || rootjQuery ).find( selector );
    
        // HANDLE: $(expr, context)
        // (which is just equivalent to: $(context).find(expr)
        } else {
          return this.constructor( context ).find( selector );
        }
    
      // HANDLE: $(DOMElement)
      } else if ( selector.nodeType ) {
        this.context = this[0] = selector;
        this.length = 1;
        return this;
    
      // HANDLE: $(function)
      // Shortcut for document ready
      } else if ( jQuery.isFunction( selector ) ) {
        return rootjQuery.ready( selector );
      }
    
      if ( selector.selector !== undefined ) {
        this.selector = selector.selector;
        this.context = selector.context;
      }
    
      return jQuery.makeArray( selector, this );
    }
    
分析:
  • 创建jQuery对象
    // selector 代表的是选择的东西
    // context 代表在什么范围内选择(不填就是选择全部)
    jQuery = function( selector, context ) {
      return new jQuery.fn.init( selector, context, rootjQuery );
    };
    
  • 每个 if需要处理的情况
    if ( typeof selector === "string" ) {
          /**
           * $('li', 'ul');
           * $('#div1') $('.box') $('div') $('#div1 div.box')
           * 
           * // 如果这样写,就是先创建之后选择
           * $('<li>');
           * $('<li>1</li><li>12</li>');
           */
        
        } else if ( selector.nodeType ) {
          // $(this) $(document)
          this.context = this[0] = selector;
          this.length = 1;
          return this;
    
        } else if ( jQuery.isFunction( selector ) ) {
          // $(function(){})
          return rootjQuery.ready( selector );
        }
    
        // $([]) $({})
        if ( selector.selector !== undefined ) {
          this.selector = selector.selector;
          this.context = selector.context;
        }
    
        return jQuery.makeArray( selector, this );
    
  • jQuery内部是以this对象来储存要操作的对象的
    console.log($('div'))的结果(所以 selector context length 都要存下来)
    在这里插入图片描述
    // jQuery中的操作
    $('li').css('background', 'red');
    // 实际上内部是使用for循环
    this = {
      0: 'li',
      1: 'li',
      2: 'li',
      length: 3
    }
    
    for(var i = 0; i < this.length; i++){
      this[i].style.background = 'red';
    }
    // 选择特定的元素
    $('li')[1].style.background = 'red';
    
    // 原生的方法(选择所有li标签)
    var aLi = document.getElementsByTagName('li');
    
  • jQuery中的init方法详解

每个jQuery对象都拥有selector context length 属性

// Start with an empty selector
selector: "",
  
// The default length of a jQuery object is 0
length: 0,

// 没有默认值
// context

其它方法详解

  • toArray
    toArray: function() {
      return core_slice.call( this );
    }
    
    // 这样子直接选出来是JSON对象 {0: div, 1: div, 2: div, length: 3}
    consoel.log($('div'))
    // 可以转换成数组 [div, div, div]
    $('div').toArray()
    
  • get
    // 不写下标就是整体,写了下标就是某一项
    get: function( num ) {
      return num == null ?
    
        // Return a 'clean' array
        this.toArray() :
    
        // Return just the object
        ( num < 0 ? this[ this.length + num ] : this[ num ] );
    }
    
  • pushStack() 用于将一个DOM元素集合加入到jQuery栈
    pushStack: function( elems ) {
      // constructor: jQuery
      /*
    	jQuery = function( selector, context ) {
          // The jQuery object is actually just the init constructor 'enhanced'
          return new jQuery.fn.init( selector, context, rootjQuery );
        }
      */
      // this.constructor() 是空的jQuery对象
      var ret = jQuery.merge( this.constructor(), elems );
    
      // 挂载到ret上面,用于回溯(end()方法要使用)
      ret.prevObject = this;
      // 作用域还是之前的作用域
      ret.context = this.context;
    
      // Return the newly-formed element set
      return ret;
    },
    
    // 最后上面的span会变红
    $('div').pushStack($('span')).css('background', 'red');
    
    // 如果想设置div变成黄色
    $('div').pushStack($('span')).css('background', 'red').end().css('background', 'yellow');
    
    // ——————————————————————————————————————————————————
    var test = document.getElementById('demo'); 
    $('div').pushStack(test).css('background-color','red').end().css('background-color','yellow');    // × test没有length属性
    $('div').pushStack([test]).css('background-color','red').end().css('background-color','yellow');
    
  • each 遍历集合
    each: function( callback, args ) {
          return jQuery.each( this, callback, args );
    }
    
  • ready:进行DOM加载(当 DOM(文档对象模型) 已经加载,并且页面(包括图像)已经完全呈现时,会发生 ready 事件。)
    ready: function( fn ) {
      // Add the callback
      jQuery.ready.promise().done( fn );
    
      return this;
    }
    
    // 有三种写法
    $(document).ready(function)
    $().ready(function)
    $(function)
    
  • slice :把匹配元素集合缩减为指定的指数范围的子集。
    slice: function() {
      return this.pushStack( core_slice.apply( this, arguments ) );
    }
    
    // 将2,3号盒子的背景颜色改为红色
    $('div').slice(1, 3).css('background', 'red');
    
  • first last eq
    first: function() {
      return this.eq( 0 );
    },
    
    last: function() {
      return this.eq( -1 );
    },
    
    eq: function( i ) {
      var len = this.length,
        j = +i + ( i < 0 ? len : 0 );
      return this.pushStack( j >= 0 && j < len ? [ this[j] ] : [] );
    },
    
    // 负数代表从后往前数,正数代表从前往后数
    $('div').eq(0).css('background', 'red');
    
  • map
    map: function( callback ) {
      return this.pushStack( jQuery.map(this, function( elem, i ) {
        return callback.call( elem, i, elem );
      }));
    }
    
    <script>
      var arr = ['a', 'b', 'c'];
      arr = $.map(arr, function(elem, i){
        return elem + i;
      })  
      console.log(arr);   // ["a0", "b1", "c2"]
    </script>
    
  • end:结束当前链条中的最近的筛选操作,并将匹配元素集还原为之前的状态。
    end: function() {
      return this.prevObject || this.constructor(null);
    }
    
  • 数组方法挂载到jQuery对象下
    push: core_push,
    sort: [].sort,
    splice: [].splice
    
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值