jQuery.アクセスソース分析

5546 ワード

基本的な理解
jQuery.attrはjQueryです.attr,jQuery.prop,jQuery.cssは下位レベルのサポートを提供して、jQueryの中で1つの比較的に特色のある地方は関数の重荷で、例えばattr、以下のいくつかの重荷があります
  • $('#box').attr('title')
  • $('#box').attr('title','タイトル')
  • $('#box').attr({title:'タイトル',data-menu-toggle:'dropdown'})
  • $('#box').attr('title',function () {....})

  • でもjQuery.を見渡すとattrコードでは、valueが存在するかどうか判断していません.ok、あなたの推測は正しいです.accessで実現しました.
    jQuery.fn.extend({  attr: function (name, value) {    return jQuery.access(this, jQuery.attr, name, value, arguments.length > 1);  },  removeAttr: function (name) {    return this.each(function () {      jQuery.removeAttr(this, name);    });  },  prop: function (name, value) {    return jQuery.access(this, jQuery.prop, name, value, arguments.length > 1);  }
    });

    ソース分析
    大まかな考え方.
  • 1.まずkey値がobjectであるか否かを判断し、もしそうであればkeyを遍歴し、jQueryを再帰的に呼び出す.アクセスし、チェーン呼び出し可能か否かのフラグビットをtrue
  • に設定.
  • 2.value値が定義するか否かを判断し、定義されている場合はset操作
  • であることを示す.
  • 2.1 set動作は、チェーン呼び出し可能な
  • である.
  • 2.2 valueがfunctionでない場合rawをtrue
  • に設定
  • 2.3 key値がnullまたはundefinedであるか否かを判断し、keyが空の値であれば
  • .
  • 2.3.1 valueが関数でない場合、またはrawがtrueである場合、fnを呼び出すのは、$('#box')である可能性がある.attr(null,{abc:'def',a:'1'})
  • 2.3.1 valueが関数である場合、fnを包装し、元のfnの役割ドメインとパラメータ
  • を変更する.
  • 2.4 fnが存在する場合、jQuery内部要素を巡回し、set操作
  • をそれぞれ実行する.
  • 3.まずsetメソッドかどうかを判断し、もしそうであればelemsを返し、get操作を実行しなければ(jQuery内部lengthが0の場合、指定したデフォルト空の値を返す)
  • .
    ソースコード
    // Multifunctional method to get and set values of a collection
        // The value/s can optionally be executed if it's a function
        /**
        attr: function (name, value) {
            return jQuery.access(this, jQuery.attr, name, value, arguments.length > 1);
        },
         *
         * @param elems jQuery this
         * @param fn   
         * @param key   
         * @param value  
         * @param chainable         ,   get  , false,   set  , true
         * @param emptyGet   jQuery           
         * @param raw value       ,  raw true,  value     ,   false,  raw    
         * @returns {*}     */
        access: function( elems, fn, key, value, chainable, emptyGet, raw ) {        var i = 0,
                length = elems.length,
                bulk = key == null; // bulk   ,  ;   ,   ;  
    
            // Sets many values
            /**
             *     key   ,         ,     key,    access  
             *
             * $('#box').attr({data:1,def:'addd'});         */
            if ( jQuery.type( key ) === "object" ) {
                chainable = true; //        
                for ( i in key ) {
                    jQuery.access( elems, fn, i, key[i], true, emptyGet, raw );
                }        // Sets one value
    
                /**
                 * $('#box').attr('customvalue','abc')
                 * $('#box').attr('customvalue',function (value) {});             */
    
            } else if ( value !== undefined ) {
                chainable = true;            if ( !jQuery.isFunction( value ) ) {
                    raw = true;
                }            if ( bulk ) { // if (key == null && value !== undefined)
                    // Bulk operations run against the entire set
                    /**
                     * $('#box').attr(undefined,'abc')
                     *
                     * jQuery.attr.call(elems,value);       , fn                     */
                    if ( raw ) {
                        fn.call( elems, value );
                        fn = null;                // ...except when executing function values
                        /**
                         * $('#box').attr(undefined,function () {})
                         *
                         * fn = bulk = jQuery.attr;
                         *
                         * fn = function (elem, key, value) {
                         *  return jQuery.attr.call(jQuery(elem),value);
                         * }
                         *                     */
                    } else { //  key    ,  ,   bulk         , fn bulk   ,    fn   
                        bulk = fn;
                        fn = function( elem, key, value ) {                        return bulk.call( jQuery( elem ), value );
                        };
                    }
                }            //jQuery.access(elems,jQuery.attr,)
    
    
                //  fn  ,        ,  key    ,        ,  set  
                if ( fn ) { //      
                    for ( ; i < length; i++ ) {
                        fn( elems[i], key,
                            raw ? value :                        /**
                             *   value     ,  value,      ,         
                             * $('#box').attr('abc',function (index,value) { index         ,value  oldValue
                             *
                             *     jQuery.attr(elements[i],key)       ,       fn 
                             * });                         */
    
    
                                value.call( elems[i], i, fn( elems[i], key ) )
                        );
                    }
                }
            }        /**
             *   chainable true,    set  ,   elems
             *      get  
             * 1.  bulk  true,    key ,  fn, elems   
             * 2.  bulk false,  key   ,             0
             *    2.1     0,  fn,  elems[0] key,  get
             *    2.2    0,       ,       emptyGet         */
            return chainable ?
                elems :            // Gets
                bulk ?
                    fn.call( elems ) :
                    length ? fn( elems[0], key ) : emptyGet;
        },