一、实现原理:

对于DOM元素,通过分配一个唯一的关联id把DOM元素和该DOM元素的数据缓存对象关联起来,关联id被附加到以jQuery.expando的值命名的属性上,数据存储在全局缓存对象jQuery.cache中。在读取、设置、移除数据时,将通过关联id从全局缓存对象jQuery.cache中找到关联的数据缓存对象,然后在数据缓存对象上执行读取、设置、移除操作。

对于Javascript对象,数据则直接存储在该Javascript对象的属性jQuery.expando上。在读取、设置、移除数据时,实际上是对Javascript对象的数据缓存对象执行读取、设置、移除操作。

为了避免jQuery内部使用的数据和用户自定义的数据发生冲突,数据缓存模块把内部数据存储在数据缓存对象上,把自定义数据存储在数据缓存对象的属性data上。

二、总体结构:

  1. // 数据缓存 Data
  2. jQuery.extend({
  3. // 全局缓存对象
  4. cache: {},
  5. // 唯一 id种子
  6. uuid:0,
  7. // 页面中每个jQuery副本的唯一标识
  8. expando: "jQuery" + ( jQuery.fn.jquery + Math.random() ).replace( /\D/g, "" ),
  9. // 是否有关联的数据
  10. hasData: function(){},
  11. // 设置、读取自定数据或内部数据
  12. data: function(elem, name, data, pvt) {},
  13. // 移除自定义数据或内部数据
  14. removeData: function(elem, name, pvt) {},
  15. // 设置、读取内部数据
  16. _data: function(elem, name, data) {},
  17. // 是否可以设置数据
  18. acceptData: function(elem){}
  19. });
  20. jQuery.fn.extend({
  21. // 设置、读取自定义数据,解析HTML5属性data-
  22. data: function(key,value){},
  23. // 移除自定义数据
  24. removeData: function(key){}
  25. });
  26. // 解析HTML5属性 data-functiondataAttr(elem,key,data){}
  27. // 检查数据缓存对象是否为空functionisEmptyDataObject(obj){}
  28. jQuery.extend({
  29. // 清空数据缓存对象
  30. cleanData: function(elems){}
  31. });

三、$.data(elem, name, data), $.data(elem, name)

$.data(elem, name, data)的使用方法:

如果传入参数name, data, 则设置任意类型的数据

  1. <!doctype html>
  2. <htmllang="en">
  3. <head>
  4. <metacharset="utf-8">
  5. <title>jQuery.data demo</title>
  6. <style>
  7. div {
  8. color: blue;
  9. }
  10. span {
  11. color: red;
  12. }
  13. </style>
  14. <scriptsrc="//code.jquery.com/jquery-1.10.2.js"></script>
  15. </head>
  16. <body>
  17. <div>
  18. The values stored were
  19. <span></span>
  20. and
  21. <span></span>
  22. </div>
  23. <script>
  24. var div = $( "div" )[ 0 ];
  25. jQuery.data( div, "test", {
  26. first: 16,
  27. last: "pizza!"
  28. });
  29. $( "span:first" ).text( jQuery.data( div, "test" ).first );
  30. $( "span:last" ).text( jQuery.data( div, "test" ).last );
  31. </script>
  32. </body>
  33. </html>

$.data(elem, name)的使用方法:

如果传入key, 未传入参数data, 则读取并返回指定名称的数据

  1. <!doctype html>
  2. <htmllang="en">
  3. <head>
  4. <metacharset="utf-8">
  5. <title>jQuery.data demo</title>
  6. <style>
  7. div {
  8. margin: 5px;
  9. background: yellow;
  10. }
  11. button {
  12. margin: 5px;
  13. font-size: 14px;
  14. }
  15. p {
  16. margin: 5px;
  17. color: blue;
  18. }
  19. span {
  20. color: red;
  21. }
  22. </style>
  23. <scriptsrc="//code.jquery.com/jquery-1.10.2.js"></script>
  24. </head>
  25. <body>
  26. <div>A div</div>
  27. <button>Get "blah" from the div</button>
  28. <button>Set "blah" to "hello"</button>
  29. <button>Set "blah" to 86</button>
  30. <button>Remove "blah" from the div</button>
  31. <p>The "blah" value of this div is <span>?</span></p>
  32. <script>
  33. $( "button" ).click( function() {
  34. var value,
  35. div = $( "div" )[ 0 ];
  36. switch ( $( "button" ).index( this ) ) {
  37. case0 :
  38. value = jQuery.data( div, "blah" );
  39. break;
  40. case1 :
  41. jQuery.data( div, "blah", "hello" );
  42. value = "Stored!";
  43. break;
  44. case2 :
  45. jQuery.data( div, "blah", 86 );
  46. value = "Stored!";
  47. break;
  48. case3 :
  49. jQuery.removeData( div, "blah" );
  50. value = "Removed!";
  51. break;
  52. }
  53. $( "span" ).text( "" + value );
  54. });
  55. </script>
  56. </body>
  57. </html>

$.data(elem, name, data), $.data(elem, name) 源码解析:

  1. jQuery.extend({
  2. // 1. 定义jQuery.data(elem, name, data, pvt)
  3. data: function( elem, name, data, pvt /* Internal Use Only */ ) {
  4. // 2. 检查是否可以设置数据
  5. if ( !jQuery.acceptData( elem ) ) {
  6. return; // 如果参数elem不支持设置数据,则立即返回
  7. }
  8. // 3 定义局部变量
  9. var privateCache, thisCache, ret,
  10. internalKey = jQuery.expando,
  11. getByName = typeof name === "string",
  12. // We have to handle DOM nodes and JS objects differently because IE6-7
  13. // can't GC object references properly across the DOM-JS boundary
  14. isNode = elem.nodeType, // elem是否是DOM元素
  15. // Only DOM nodes need the global jQuery cache; JS object data is
  16. // attached directly to the object so GC can occur automatically
  17. cache = isNode ? jQuery.cache : elem, // 如果是DOM元素,为了避免javascript和DOM元素之间循环引用导致的浏览器(IE6/7)垃圾回收机制不起作用,要把数据存储在全局缓存对象jQuery.cache中;对于javascript对象,来及回收机制能够自动发生,不会有内存泄露的问题,因此数据可以查收存储在javascript对象上
  18. // Only defining an ID for JS objects if its cache already exists allows
  19. // the code to shortcut on the same path as a DOM node withnocache
  20. id = isNode ? elem[ internalKey ] : elem[ internalKey ] && internalKey,
  21. isEvents = name === "events";
  22. // Avoid doing any more work than we need to when trying to get data on an
  23. // object that has no data at all
  24. // 4. 如果是读取数据,但没有数据,则返回
  25. if ( (!id || !cache[id] || (!isEvents && !pvt && !cache[id].data)) && getByName && data === undefined ) {
  26. return;
  27. // getByName && data === undefined 如果name是字符串,data是undefined, 说明是在读取数据
  28. // !id || !cache[id] || (!isEvents && !pvt && !cache[id].data 如果关联id不存在,说明没有数据;如果cache[id]不存在,也说明没有数据;如果是读取自动以数据,但cache[id].data不存在,说明没有自定义数据
  29. }
  30. // 5. 如果关联id不存在,则分配一个
  31. if ( !id ) {
  32. // Only DOM nodes need a new unique ID foreach element since their data
  33. // ends up in the globalcacheif ( isNode ) {
  34. elem[ internalKey ] = id = ++jQuery.uuid; // 对于DOM元素,jQuery.uuid会自动加1,并附加到DOM元素上
  35. } else {
  36. id = internalKey; // 对于javascript对象,关联id就是jQuery.expando
  37. }
  38. }
  39. // 6. 如果数据缓存对象不存在,则初始化为空对象{}
  40. if ( !cache[ id ] ) {
  41. cache[ id ] = {};
  42. // Avoids exposing jQuery metadata on plain JS objects when the object
  43. // is serialized using JSON.stringify
  44. if ( !isNode ) {
  45. cache[ id ].toJSON = jQuery.noop; // 对于javascript对象,设置方法toJSON为空函数,以避免在执行JSON.stringify()时暴露缓存数据。如果一个对象定义了方法toJSON(),JSON.stringify()在序列化该对象时会调用这个方法来生成该对象的JSON元素
  46. }
  47. }
  48. // An object can be passed to jQuery.data instead of a key/value pair; this gets
  49. // shallow copied over onto the existing cache
  50. // 7. 如果参数name是对象或函数,则批量设置数据
  51. if ( typeof name === "object" || typeof name === "function" ) {
  52. if ( pvt ) {
  53. cache[ id ] = jQuery.extend( cache[ id ], name ); // 对于内部数据,把参数name中的属性合并到cache[id]中
  54. } else {
  55. cache[ id ].data = jQuery.extend( cache[ id ].data, name ); // 对于自定义数据,把参数name中的属性合并到cache[id].data中
  56. }
  57. }
  58. // 8. 如果参数data不是undefined, 则设置单个数据
  59. privateCache = thisCache = cache[ id ];
  60. // jQuery data() is stored in a separate object inside the object's internal data
  61. // cacheinorderto avoid key collisions between internal dataanduser-defined
  62. // data.
  63. if ( !pvt ) {
  64. if ( !thisCache.data ) {
  65. thisCache.data = {};
  66. }
  67. thisCache = thisCache.data;
  68. }
  69. if ( data !== undefined ) {
  70. thisCache[ jQuery.camelCase( name ) ] = data;
  71. }
  72. // Users should not attempt to inspect the internal events object using jQuery.data,
  73. // it is undocumented and subject to change. But does anyone listen? No.
  74. // 9. 特殊处理eventsif ( isEvents && !thisCache[ name ] ) { // 如果参数name是字符串"events",并且未设置过自定义数据"events",则返回事件婚车对象,在其中存储了事件监听函数。
  75. return privateCache.events;
  76. }
  77. // Checkforboth converted-to-camel and non-converted data property names
  78. // If a data property was specified
  79. //10. 如果参数name是字符串,则读取单个数据
  80. if ( getByName ) {
  81. // First Try to find as-is property data
  82. ret = thisCache[ name ]; // 先尝试读取参数name对应的数据
  83. // Test for null|undefined property data
  84. if ( ret == null ) { // 如果未取到,则把参数name转换为驼峰式再次尝试读取对应的数据
  85. // Try to find the camelCased property
  86. ret = thisCache[ jQuery.camelCase( name ) ];
  87. }
  88. } else { // 11. 如果未传入参数name,data,则返回数据缓存对象
  89. ret = thisCache;
  90. }
  91. return ret;
  92. },
  93. // For internal useonly.
  94. _data: function( elem, name, data ) {
  95. return jQuery.data( elem, name, data, true );
  96. },
  97. });

四、.data(key, value), .data(key)

使用方法:

  1. $( "body" ).data( "foo", 52 ); // 传入key, value
  2. $( "body" ).data( "bar", { myType: "test", count: 40 } ); // 传入key, value
  3. $( "body" ).data( { baz: [ 1, 2, 3 ] } ); // 传入key, value
  4. $( "body" ).data( "foo" ); // 52 // 传入key
  5. $( "body" ).data(); // 未传入参数

HTML5 data attriubutes:

  1. <div data-role="page" data-last-value="43" data-hidden="true" data-options='{"name":"John"}'></div>
  2. $( "div" ).data( "role" ) === "page";
  3. $( "div" ).data( "lastValue" ) === 43;
  4. $( "div" ).data( "hidden" ) === true;
  5. $( "div" ).data( "options" ).name === "John";

.data(key, value), .data(key) 源码解析

  1. jQuery.fn.extend({
  2. // 1. 定义.data(key, value)
  3. data: function( key, value ) {
  4. var parts, attr, name,
  5. data = null;
  6. // 2. 未传入参数的情况if ( typeof key === "undefined" ) {
  7. if ( this.length ) { // 如果参数key是undefined, 即参数格式是.data(), 则调用方法jQuery.data(elem, name, data, pvt)获取第一个匹配元素关联的自定义数据缓存对象,并返回。
  8. data = jQuery.data( this[0] );
  9. if ( this[0].nodeType === 1 && !jQuery._data( this[0], "parsedAttrs" ) ) {
  10. attr = this[0].attributes;
  11. for ( var i = 0, l = attr.length; i < l; i++ ) {
  12. name = attr[i].name;
  13. if ( name.indexOf( "data-" ) === 0 ) {
  14. name = jQuery.camelCase( name.substring(5) );
  15. dataAttr( this[0], name, data[ name ] );
  16. }
  17. }
  18. jQuery._data( this[0], "parsedAttrs", true );
  19. }
  20. }
  21. return data;
  22. // 3. 参数key 是对象的情况,即参数格式是.data(key),则遍历匹配元素集合,为每个匹配元素调用方法jQuery.data(elem, name, data,pvt)批量设置数据
  23. } elseif ( typeof key === "object" ) {
  24. returnthis.each(function() {
  25. jQuery.data( this, key );
  26. });
  27. }
  28. // 4. 只传入参数key的情况 如果只传入参数key, 即参数格式是.data(key),则返回第一个匹配元素的指定名称数据
  29. parts = key.split(".");
  30. parts[1] = parts[1] ? "." + parts[1] : "";
  31. if ( value === undefined ) {
  32. data = this.triggerHandler("getData" + parts[1] + "!", [parts[0]]);
  33. // Try to fetch any internally stored data firstif ( data === undefined && this.length ) {
  34. data = jQuery.data( this[0], key );
  35. data = dataAttr( this[0], key, data );
  36. }
  37. return data === undefined && parts[1] ?
  38. this.data( parts[0] ) :
  39. data;
  40. // 5. 传入参数key和value的情况 即参数格式是.data(key, value),则为每个匹配元素设置任意类型的数据,并触发自定义事件setData, changeData
  41. } else {
  42. returnthis.each(function() {
  43. var self = jQuery( this ),
  44. args = [ parts[0], value ];
  45. self.triggerHandler( "setData" + parts[1] + "!", args );
  46. jQuery.data( this, key, value );
  47. self.triggerHandler( "changeData" + parts[1] + "!", args );
  48. });
  49. }
  50. },
  51. removeData: function( key ) {
  52. returnthis.each(function() {
  53. jQuery.removeData( this, key );
  54. });
  55. }
  56. });
  57. // 6. 函数dataAttr(elem, key, data)解析HTML5属性data-functiondataAttr( elem, key, data ) {
  58. // If nothing was found internally, try to fetch any// data from the HTML5 data-* attribute// 只有参数data为undefined时,才会解析HTML5属性data-if ( data === undefined && elem.nodeType === 1 ) {
  59. var name = "data-" + key.replace( rmultiDash, "-$1" ).toLowerCase();
  60. data = elem.getAttribute( name );
  61. if ( typeof data === "string" ) {
  62. try {
  63. data = data === "true" ? true :
  64. data === "false" ? false :
  65. data === "null" ? null :
  66. jQuery.isNumeric( data ) ? parseFloat( data ) :
  67. rbrace.test( data ) ? jQuery.parseJSON( data ) :
  68. data;
  69. } catch( e ) {}
  70. // Make sure we set the data so it isn't changed later
  71. jQuery.data( elem, key, data );
  72. } else {
  73. data = undefined;
  74. }
  75. }
  76. return data;
  77. }

五、$.removeData(elem, name),.removeData(key)

使用方法:

  1. <!doctype html>
  2. <htmllang="en">
  3. <head>
  4. <metacharset="utf-8">
  5. <title>jQuery.removeData demo</title>
  6. <style>
  7. div {
  8. margin: 2px;
  9. color: blue;
  10. }
  11. span {
  12. color: red;
  13. }
  14. </style>
  15. <scriptsrc="//code.jquery.com/jquery-1.10.2.js"></script>
  16. </head>
  17. <body>
  18. <div>value1 before creation: <span></span></div>
  19. <div>value1 after creation: <span></span></div>
  20. <div>value1 after removal: <span></span></div>
  21. <div>value2 after removal: <span></span></div>
  22. <script>
  23. var div = $( "div" )[ 0 ];
  24. $( "span:eq(0)" ).text( "" + $( "div" ).data( "test1" ) ); //undefined
  25. jQuery.data( div, "test1", "VALUE-1" );
  26. jQuery.data( div, "test2", "VALUE-2" );
  27. $( "span:eq(1)" ).text( "" + jQuery.data( div, "test1" ) ); // VALUE-1
  28. jQuery.removeData( div, "test1" );
  29. $( "span:eq(2)" ).text( "" + jQuery.data( div, "test1" ) ); // undefined
  30. $( "span:eq(3)" ).text( "" + jQuery.data( div, "test2" ) ); // value2
  31. </script>
  32. </body>
  33. </html>
  34. <!doctype html>
  35. <htmllang="en">
  36. <head>
  37. <metacharset="utf-8">
  38. <title>removeData demo</title>
  39. <style>
  40. div {
  41. margin: 2px;
  42. color: blue;
  43. }
  44. span {
  45. color: red;
  46. }
  47. </style>
  48. <scriptsrc="//code.jquery.com/jquery-1.10.2.js"></script>
  49. </head>
  50. <body>
  51. <div>value1 before creation: <span></span></div>
  52. <div>value1 after creation: <span></span></div>
  53. <div>value1 after removal: <span></span></div>
  54. <div>value2 after removal: <span></span></div>
  55. <script>
  56. $( "span:eq(0)" ).text( "" + $( "div" ).data( "test1" ) ); // undefined
  57. $( "div" ).data( "test1", "VALUE-1" );
  58. $( "div" ).data( "test2", "VALUE-2" );
  59. $( "span:eq(1)" ).text( "" + $( "div").data( "test1" ) ); // VALUE-1
  60. $( "div" ).removeData( "test1" );
  61. $( "span:eq(2)" ).text( "" + $( "div" ).data( "test1" ) ); // undefined
  62. $( "span:eq(3)" ).text( "" + $( "div" ).data( "test2" ) ); // VALUE-2
  63. </script>
  64. </body>
  65. </html>

$.removeData(elem, name),.removeData(key) 源码解析:

  1. $.extend({
  2. // jQuery.removeData(elem,name,pvt)用于移除通过jQuery.data()设置的数据
  3. removeData: function( elem, name, pvt /* Internal Use Only */ ) {
  4. if ( !jQuery.acceptData( elem ) ) {
  5. return;
  6. }
  7. var thisCache, i, l,
  8. // Reference to internal data cache key
  9. internalKey = jQuery.expando,
  10. isNode = elem.nodeType,
  11. // See jQuery.data for more information
  12. cache = isNode ? jQuery.cache : elem,
  13. // See jQuery.data for more information
  14. id = isNode ? elem[ internalKey ] : internalKey;
  15. // If there is already no cache entry for this object, there is no// purpose in continuingif ( !cache[ id ] ) {
  16. return;
  17. }
  18. // 如果传入参数name, 则移除一个或多个数据if ( name ) {
  19. thisCache = pvt ? cache[ id ] : cache[ id ].data;
  20. if ( thisCache ) { // 只有数据缓存对象thisCache存在时,才有必要移除数据// Support array or space separated string names for data keysif ( !jQuery.isArray( name ) ) {
  21. // try the string as a key before any manipulationif ( name in thisCache ) {
  22. name = [ name ];
  23. } else {
  24. // split the camel cased version by spaces unless a key with the spaces exists
  25. name = jQuery.camelCase( name );
  26. if ( name in thisCache ) {
  27. name = [ name ];
  28. } else {
  29. name = name.split( " " );
  30. }
  31. }
  32. }
  33. // 遍历参数name中的数据名,用运算符delete逐个从数据缓存对象thisCache中移除for ( i = 0, l = name.length; i < l; i++ ) {
  34. delete thisCache[ name[i] ];
  35. }
  36. // If there is no data left in the cache, we want to continue// and let the cache object itself get destroyedif ( !( pvt ? isEmptyDataObject : jQuery.isEmptyObject )( thisCache ) ) {
  37. return;
  38. }
  39. }
  40. }
  41. // See jQuery.data for more information// 删除自定义数据缓存对象cache[id].dataif ( !pvt ) {
  42. delete cache[ id ].data;
  43. // Don't destroy the parent cache unless the internal data object// had been the only thing left in itif ( !isEmptyDataObject(cache[ id ]) ) {
  44. return;
  45. }
  46. }
  47. // Browsers that fail expando deletion also refuse to delete expandos on// the window, but it will allow it on all other JS objects; other browsers// don't care// Ensure that `cache` is not a window object #10080// 删除数据缓存对象cache[id]if ( jQuery.support.deleteExpando || !cache.setInterval ) {
  48. delete cache[ id ];
  49. } else {
  50. cache[ id ] = null;
  51. }
  52. // We destroyed the cache and need to eliminate the expando on the node to avoid// false lookups in the cache for entries that no longer exist// 删除DOM元素上扩展的jQuery.expando属性if ( isNode ) {
  53. // IE does not allow us to delete expando properties from nodes,// nor does it have a removeAttribute function on Document nodes;// we must handle all of these casesif ( jQuery.support.deleteExpando ) {
  54. delete elem[ internalKey ];
  55. } elseif ( elem.removeAttribute ) {
  56. elem.removeAttribute( internalKey );
  57. } else {
  58. elem[ internalKey ] = null;
  59. }
  60. }
  61. }
  62. });
  63. jQuery.fn.extend({
  64. removeData: function( key ) {
  65. returnthis.each(function() {
  66. jQuery.removeData( this, key );
  67. });
  68. }
  69. });
  70. // checks a cache object for emptinessfunctionisEmptyDataObject( obj ) {
  71. for ( var name in obj ) {
  72. // if the public data object is empty, the private is still emptyif ( name === "data" && jQuery.isEmptyObject( obj[name] ) ) {
  73. continue;
  74. }
  75. if ( name !== "toJSON" ) {
  76. return false;
  77. }
  78. }
  79. return true;
  80. }

六、$.hasData(elem)

使用方法:

  1. <!doctype html>
  2. <htmllang="en">
  3. <head>
  4. <metacharset="utf-8">
  5. <title>jQuery.hasData demo</title>
  6. <scriptsrc="//code.jquery.com/jquery-1.10.2.js"></script>
  7. </head>
  8. <body>
  9. <p>Results: </p>
  10. <script>
  11. var $p = jQuery( "p" ), p = $p[ 0 ];
  12. $p.append( jQuery.hasData( p ) + " " ); // false
  13. $.data( p, "testing", 123 );
  14. $p.append( jQuery.hasData( p ) + " " ); // true
  15. $.removeData( p, "testing" );
  16. $p.append( jQuery.hasData( p ) + " " ); // false
  17. $p.on( "click", function() {} );
  18. $p.append( jQuery.hasData( p ) + " " ); // true
  19. $p.off( "click" );
  20. $p.append( jQuery.hasData( p ) + " " ); // false
  21. </script>
  22. </body>
  23. </html>

$.hasData(elem) 源码解析:

  1. $.extend({
  2. hasData: function( elem ) {
  3. elem = elem.nodeType ? jQuery.cache[ elem[jQuery.expando] ] : elem[ jQuery.expando ];
  4. return !!elem && !isEmptyDataObject( elem );
  5. // 如果关联的数据缓存对象存在,并且含有数据,则返回true, 否则返回false。 这里用两个逻辑非运算符! 把变量elem转换为布尔值
  6. }
  7. });

jQuery数据缓存$.data 的使用以及源码解析的更多相关文章

  1. 【Android初级】利用startActivityForResult返回数据到前一个Activity(附源码+解析)

    在Android里面,从一个Activity跳转到另一个Activity.再返回,前一个Activity默认是能够保存数据和状态的.但这次我想通过利用startActivityForResult达到相 ...

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

    jQuery中有三种添加数据的方法,$().attr(),$().prop(),$().data().但是前面两种是用来在元素上添加属性值的,只适合少量的数据,比如:title,class,name等 ...

  3. [源码解析] PyTorch 分布式(1) --- 数据加载之DistributedSampler

    [源码解析] PyTorch 分布式(1) --- 数据加载之DistributedSampler 目录 [源码解析] PyTorch 分布式(1) --- 数据加载之DistributedSampl ...

  4. [源码解析] PyTorch 分布式(2) --- 数据加载之DataLoader

    [源码解析] PyTorch 分布式(2) --- 数据加载之DataLoader 目录 [源码解析] PyTorch 分布式(2) --- 数据加载之DataLoader 0x00 摘要 0x01 ...

  5. MyBatis源码解析之数据源(含数据库连接池简析)

    一.概述: 常见的数据源组件都实现了javax.sql.DataSource接口: MyBatis不但要能集成第三方的数据源组件,自身也提供了数据源的实现: 一般情况下,数据源的初始化过程参数较多,比 ...

  6. Laravel源码解析之model(代码)

    本篇文章给大家带来的内容是关于Laravel源码解析之model(代码),有一定的参考价值,有需要的朋友可以参考一下,希望对你有所帮助. 前言 提前预祝猿人们国庆快乐,吃好.喝好.玩好,我会在电视上看 ...

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

    上一课主要讲了jQuery中的缓存机制Data构造方法的源码解析,这一课主要讲jQuery是如何利用Data对象实现有关缓存机制的静态方法和实例方法的.我们接下来,来看这几个静态方法和实例方法的源码解 ...

  8. JQuery源码解析(九)

    jQuery回调对象 jQuery.Callbacks一般开发者接触的很少,虽然jQuery向开发者提供了外部接口调用,但是$.Callbacks()模块的开发目的是为了给内部$.ajax() 和 $ ...

  9. jQuery源码解析资源便签

    最近开始解读jQuery源码,下面的链接都是搜过来的,当然妙味课堂 有相关的一系列视频,长达100多期,就像一只蜗牛慢慢爬, 至少品读三个框架,以后可以打打怪,自己造造轮子. 完全理解jQuery源代 ...

随机推荐

  1. mysql数据的导入导出

    2017-12-15       一. mysqldump工具基本用法,不适用于大数据备份   1. 备份所有数据库: mysqldump -u root -p --all-databases > ...

  2. POJ-3126-Prime Path(BFS)

    Prime Path Time Limit: 1000MS   Memory Limit: 65536K Total Submissions: 27852   Accepted: 15204 Desc ...

  3. JavaWeb学习笔记(二十一)—— 监听器Listener

    一.监听器概述 JavaWeb中的监听器是Servlet规范中定义的一种特殊类,它用于监听web应用程序中的ServletContext, HttpSession和 ServletRequest等域对 ...

  4. centos的 / ~ - 的意思

    . 当前目录 .. 上一层目录 - 前一个工作目录,上一次操作的目录 cd - 会切换都上次你操作的目录 ~ 当前[用户]所在的家目录/ root的根目录

  5. [CH3803] 扑克牌 (期望DP+记忆化搜索)

    [题目链接] [CH3803] 扑克牌 [题面描述] \(54\)张牌,每次随机摸一张,求得到 A张黑桃 B张红桃 C张梅花 D张方块 的期望步数.特别地,大王和小王可以当做任意一种花色,当然,会选择 ...

  6. 洛谷 P4248 / loj 2377 [AHOI2013] 差异 题解【后缀自动机】【树形DP】

    可能是一个 SAM 常用技巧?感觉 SAM 的基础题好多啊.. 题目描述 给定一个长度为 \(n\) 的字符串 \(S\) ,令 \(T_i\) 表示它从第 \(i\) 个字符开始的后缀,求: \[ ...

  7. google hack使用集锦

    转载:https://blog.csdn.net/weixin_42127015/article/details/84472777 关于google hack的几个基础过滤器使用[请务必谨记,过滤器虽 ...

  8. Java 抽象类的简单使用

    自己做的一点笔记... 抽象类:使用关键词 abstract 进行修饰,抽象类不能生成对象(实例化),且含有抽象方法(使用 abstract 进行声明,并且没有方法体). 特点: 1️⃣  抽象类不一 ...

  9. grunt 实例构建(四)

    相关插件的引用: grunt-usemin  对页面的操作 grunt-contrib-cssmin  压缩css load-grunt-tasks 瘦身gruntfile grunt-rev给md5 ...

  10. python设计模式--读书笔记

    GoF在其设计模式一书中提出了23种设计模式,并将其分为三类: 创建型模式 将对象创建的细节隔离开来,代码与所创建的对象的类型无关. 结构型模式 简化结构,识别类与对象间的关系,重点关注类的继承和组合 ...