日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

jquery源码解析:jQuery数据缓存机制详解2

發布時間:2025/4/5 编程问答 44 豆豆
生活随笔 收集整理的這篇文章主要介紹了 jquery源码解析:jQuery数据缓存机制详解2 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

上一課主要講了jQuery中的緩存機制Data構造方法的源碼解析,這一課主要講jQuery是如何利用Data對象實現有關緩存機制的靜態方法和實例方法的。我們接下來,來看這幾個靜態方法和實例方法的源碼解析:

data_user = new Data(); ? ?//對外使用的數據緩存對象
data_priv = new Data(); ? ?//內部的數據緩存對象,內部使用

jQuery.extend({ ? ? ?//在jQuery中添加靜態方法
  acceptData: Data.accepts, ? //調用Data構造函數的accepts靜態方法

  hasData: function( elem ) { ? ?//是否有這個屬性
    return data_user.hasData( elem ) || data_priv.hasData( elem );
  },

  data: function( elem, name, data ) {
    return data_user.access( elem, name, data );
  },

  removeData: function( elem, name ) {
    data_user.remove( elem, name );
  },

  _data: function( elem, name, data ) { ? ?//_代表私有的方法,不對外
    return data_priv.access( elem, name, data );
  },

  _removeData: function( elem, name ) {
    data_priv.remove( elem, name );
  }
});

靜態方法,是直接調用Data原型上的方法,而上一課已經詳細講解了這個Data的原型,可以參照上一課。而在jQuery緩存系統中,我們經常使用的就是以下這幾個實例方法:

jQuery.fn.extend({ ?//在jQuery原型上添加實例方法

?  data: function( key, value ) { ? //一個參數時是獲取數據,兩個參數時是設置數據?  

    var attrs, name,
      elem = this[ 0 ], ?//找到一組元素中的第一個,如果是獲取操作,只獲取一個元素,如果是設置,就設置這一組元素
        i = 0,
          data = null;

    if ( key === undefined ) { ?//當不傳入參數時,就代表取這個元素的所有數據,比如:$("div").data();
      if ( this.length ) { ? //如果有元素
        data = data_user.get( elem ); ?//獲取這個元素的數據

        //下面這一段代碼是來處理HTML5中的自定義屬性data-xxx的。比如:<div id="div1" data-chao-ji="dan"></div>,$("#div1")[0].dataset.chaoJi等于"dan"(HTML5寫法)。$("#div1").data("chaoJi")等于"dan"。jQuery緩存系統會把HTML5自定義屬性data-xxx這種格式的數據自動緩存起來。

        if ( elem.nodeType === 1 && !data_priv.get( elem, "hasDataAttrs" ) ) {//元素是否是Element,元素是否有hasDataAttrs屬性,第一次是沒有的,也就是undefined。data_priv是內部使用的Data對象,不會影響到外部使用的Data對象data_user。
          attrs = elem.attributes; ?//獲取元素所有的屬性
          for ( ; i < attrs.length; i++ ) {
            name = attrs[ i ].name; ? ? //得到每一個屬性的名字

            if ( name.indexOf( "data-" ) === 0 ) { ? ?//如果元素中的屬性名有data-開頭的字符串,就進入到if語句
              name = jQuery.camelCase( name.slice(5) ); ? //取data-后面的字符串,也就是chao-ji,然后轉駝峰格式,也就是變成chaoJi。

              dataAttr( elem, name, data[ name ] ); //把data-開頭的屬性名的值添加到緩存系統中
            }
          }
          data_priv.set( elem, "hasDataAttrs", true ); //設置此元素的hasDataAttrs屬性值為true
        }
      }

      return data;
    }

    if ( typeof key === "object" ) { ?//比如:$("#div1").data({name:"chaojidan",age:"25"});
      return this.each(function() { ?//對每個元素,都在數據緩存中設置json中的屬性值
        data_user.set( this, key );
      });
    }

    return jQuery.access( this, function( value ) { ? ?//access的第一個參數是所有元素,第二個參數是回調,第三個參數是key值,第四個參數是value值。第五個參數的作用是來決定回調是用來設置數據還是獲取數據的(true代表設置操作,false代表獲取操作)。第六個參數和第七個參數是內部使用的,我們不用管。
      var data,
        camelKey = jQuery.camelCase( key );

      if ( elem && value === undefined ) { ? //如果value為空的話,就代表參數只有一個,那么arguments。length=1 >1,返回false,因此代表獲取操作,獲取元素elem在緩存系統中的key屬性值
        data = data_user.get( elem, key ); ? //獲取數據
        if ( data !== undefined ) { ? //如果找到,就直接返回
          return data;
        }

        data = data_user.get( elem, camelKey ); ? //如果沒找到,就再找key的駝峰方式的屬性值,比如:$("#div1").data("name-age"),它會先找name-age這種屬性名的值,如果沒找到,就找nameAge這種屬性名的值。
        if ( data !== undefined ) {
          return data;
        }

        data = dataAttr( elem, camelKey, undefined ); //如果都沒找到,就找HTML5自定義屬性data-xxx的值,比如:元素div上的data-name-age的屬性值。
        if ( data !== undefined ) {
          return data;
        }

        return;
      }

      this.each(function() { ? //如果value存在,就代表是設置操作。就循環所有元素,對每個元素都設置
        var data = data_user.get( this, camelKey ); //先去緩存系統中取key的駝峰形式的屬性值

        data_user.set( this, camelKey, value ); ? //然后把值設置給key的駝峰形式的屬性名

        if ( key.indexOf("-") !== -1 && data !== undefined ) { ?//如果key包含"-",并且之前取到的key的駝峰形式的屬性值存在,那么就把此駝峰形式的屬性值,賦給key這個屬性名。舉個例子:$("#div1").data("name-age","1"),這時緩存系統中會存儲nameAge:1,然后我再$("#div1").data("name-age","2"),這時data = 1,nameAge:2,進入if語句,緩存系統會再存儲name-age:1。
          data_user.set( this, key, value );
        }
      });
    }, null, value, arguments.length > 1, null, true );

  },

  removeData: function( key ) { ? ?//刪除數據
    return this.each(function() {
      data_user.remove( this, key );
    });
  }

});

function dataAttr( elem, key, data ) { ? //key=chaoJi
  var name;

  if ( data === undefined && elem.nodeType === 1 ) { ? //首先判斷數據緩存中是否有此名字的屬性值,如果沒有,并且元素是Element,就進入if語句。如果數據緩存中已經有了此名字的屬性值,那么就直接返回這個值。意思就是:當HTML5的data-xxx的屬性名xxx與jQuery通過data方法添加到數據緩存的屬性名xxx是一樣的,那么你通過data方法訪問時,獲取到的值是數據緩存中的xxx屬性值,而不是HTML5的data-xxx的屬性值,只有數據緩存沒有這個xxx的屬性值時,才會去取HTML5的data-xxx的屬性值。
    name = "data-" + key.replace( rmultiDash, "-$1" ).toLowerCase(); ?//rmultiDash = /([A-Z])/g;取大寫字母,也就是J,然后用-J代替J,這時key是chao-Ji,然后轉小寫,因此變成chao-ji。name= "data-chao-ji"
    data = elem.getAttribute( name ); ? //得到元素上的這個HTML5自定義屬性的屬性值"dan"

    if ( typeof data === "string" ) { ? ?//如果屬性值是字符串就保存到緩存系統
      try {
        data = data === "true" ? true : ?
          data === "false" ? false :
            data === "null" ? null :
              +data + "" === data ? +data : ?//如果是數字字符串,就存入數字
                rbrace.test( data ) ? JSON.parse( data ) : ?//rbrace判斷是否是一個json字符串,如果是就解析成json。
                  data; ? //如果是字符串,就直接返回字符串
      } catch( e ) {}

      data_user.set( elem, key, data );
    } else { ? //如果不是字符串就直接返回undefined,也就是說HTML5的data-xxx的屬性值只能是一個字符串,如果不是,那么你通過jQuery的data(xxx)方法獲取時,是獲取不到的,返回undefined。
      data = undefined;
    }
  }
  return data;
}

緩存系統到此結束,下一課將講解隊列Queue的實現原理。

大家不要以為這就是源碼粘貼,其實里面的注釋是非常重要的,有些復雜的,我都會舉例子說明,因此看起來不會很難。請看里面的注釋。

?

?

?

加油!

轉載于:https://www.cnblogs.com/chaojidan/p/4181630.html

總結

以上是生活随笔為你收集整理的jquery源码解析:jQuery数据缓存机制详解2的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。