很多同学在项目中都喜欢将数据存储在HTMLElement属性上,如

1
2
3
4
<div data="some data">Test</div>
<script>
    div.getAttribute('data'); // some data
</script>

给页面中div添加了自定义属性“data”及值“some data”。后续JS代码中使用getAttribute获取。

jQuery从1.2.3开始提供了data/removeData方法用来存储/删除数据。1.6.1代码片段

1
2
3
4
5
6
jQuery.extend({
    cache: {},
    // Please use with caution
    uuid: 0,
    ...
});

即给jQuery添加了静态字段/方法,有jQuery.cache/jQuery.uuid/jQuery.expando等。下面分别介绍

jQuery.cache 空对象,用来缓存。它的结构较复杂。

jQuery.uuid 自增唯一的数字。

jQuery.expando 字符串,使用Math.random生成,去掉了非数字字符。它作为HTMLElement或JS对象的属性名。

1
expando: "jQuery" + ( jQuery.fn.jquery + Math.random() ).replace( /\D/g, "" ),

jQuery.noData JS对象,对于指定的HTMLElement禁用data方法。如embed、applet。

jQuery.hasData 用来判断HTMLElement或JS对象是否具有数据。返回true或false。即如果调用了jQuery.data方法添加了属性,则返回true。

1
2
3
4
5
6
7
<div>aa</div>
<script>
    var div = document.getElementsByTagName('div')[0];
    $.hasData(div); // false
    $.data(div, 'name','jack');
    $.hasData(div); // true
</script>

jQuery.acceptData 用来判断该元素是否能接受数据,返回true或false。在jQuery.data中使用。

jQuery.data 这是提供给客户端程序员使用的方法,它同时是setter/getter。

  1. 传一个参数,返回附加在指定元素的所有数据,即thisCachejQuery.data(el); // thisCache
  2. 传二个参数,返回指定的属性值jQuery.data(el, 'name');
  3. 传三个参数,设置属性及属性值jQuery.data(el, 'name', 'jack');jQuery.data(el, 'uu', {});
  4. 传四个参数,第四个参数pvt仅提供给jQuery库自身使用。即jQuery._data方法中传true。因为jQuery的事件模块严重依赖于jQuery.data,为避免人为的不小心重写在这个版本中加入的

jQuery.removeData 删除数据。

上面是jQuery数据缓存模块的整体概述,下面详细说下jQuery.data方法。jQuery.data为两种对象提供缓存:JS对象和HTMLElement

1
2
3
4
5
6
7
8
9
10
11
12
// 为JS对象提供缓存
var myObj = {};
$.data(myObj, 'name''jack');
$.data(myObj, 'name'); // jack
 
// 为HTMLElement提供缓存
<div id="xx"></div>
<script>
    var el = document.getElementById('xx');
    $.data(el, 'name''jack');
    $.data(el, 'name'); // jack
</script>

内部实现上也是有区别的,

1,为JS对象提供缓存时,直接将数据保存在JS对象上。cache为JS对象。此时会偷偷的给JS对象添加个属性(类似于jQuery16101803968874529044),属性值也是个JS对象。举例说明

1
2
3
var myObj = {};
$.data(myObj, 'name''jack');
console.log(myObj);

myObj的结构如下

1
2
3
4
5
myObj = {
    jQuery16101803968874529044 : {
        name : 'jack'
    }
}

“jQuery16101803968874529044”这个字符串在data内部命名为id(注意并非HTMLElement元素的id),它实际就是jQuery.expando。上面已经提到它是在jQuery.js引入到页面后随机生成的。

2,为HTMLElement提供缓存时,却不会直接保存在HTMLElement上。而是保存在jQuery.cache上。cache为jQuery.cache。此时先给HTMLElement添加属性(类似于jQuery16101803968874529044),属性值为数字(1,2,3递增)。即只将一些数字保存在了HTMLElement上,不会直接将数据置入。这是因为IE老版本中可能会存在内存泄露危险。而HTMLElement如何与jQuery.cache建立联系呢? 还是id。刚刚提到属性值数字就是id。举例说明

1
2
3
4
5
6
7
<div id="xx"></div>
<script>
    var el = document.getElementById('xx');
    $.data(el, 'name''jack');
    console.log(el[jQuery.expando]); // 1
    console.log(jQuery.cache); // {1 : {name:'jack'}}
</script>

  

el 上添加了属性jQuery.expando,值为id,这个id是从1开始递增的。而id又作为jQuery.cache的属性(key)。这样就HTMLElement就与jQuery.cache建立了联系。如图

不知注意到没有,jQuery.data还有第四个参数pvt,这个参数只在jQuery._data中使用。

1
2
3
4
// For internal use only.
_data: function( elem, name, data ) {
    return jQuery.data( elem, name, data, true );
},

  

jQuery._data从命名上就指定它是私有的,使用jQuery的客户端程序员不应该去调用该方法。jQuery的API文档上也不会公开它。

jQuery的数据缓存模块从1.2.3到1.6.1几乎每个版本都在变。jQuery._data的提出就是为了避免客户端程序员覆盖/重写了默写模块。如jQuery事件模块中事件handler等就使用jQuery.data存储,如果重写了该模块。那么事件模块将瘫痪。因此特意添加了pvt参数及jQuery._data方法。

但如果你刻意要破坏,那么还是可以做的。如下

1
2
3
4
5
6
7
8
9
10
<div id="xx">Test</div>
<script>
    $('#xx').click(function(){
        alert('click');
    });
    // 语句1
    $.data($('#xx')[0], 'events'''true);
    // 语句2
    //$._data($('#xx')[0], 'events', '');
</script>

  

点击div[id=xx]将不会触发点击事件。

整个jQuery.data设置(set)数据缓存的过程就是如此,理解的这个。取数据(get)的过程就好理解了。不重复。

最后,我会给zChian.js添加zChain.data/removeData方法,因为是“迷你版”,仅给HTMLElement添加数据缓存。请注意。

相关:

http://msdn.microsoft.com/en-us/library/Bb250448

http://bugs.jquery.com/ticket/6807

z.js

读jQuery之六(缓存数据)的更多相关文章

  1. jQuery缓存数据

    很多同学在项目中都喜欢将数据存储在HTMLElement属性上,如 1 2 3 4 <div data="some data">Test</div> < ...

  2. 从jQuery的缓存到事件监听

    不知道大家有没有发现,用jQuery选择器"选择"之后的DOM上会添加jQuery*********属性. <DIV id=d1 jQuery1294122065250=&q ...

  3. 读jQuery源码 jQuery.data

    var rbrace = /(?:\{[\s\S]*\}|\[[\s\S]*\])$/, rmultiDash = /([A-Z])/g; function internalData( elem, n ...

  4. angluar1+ionic详情页返回在原来的位置(缓存数据和页面高度)

    因为是老项目,近期开发遇到了个需求就是从详情页按返回按钮要求返回到原来列表的页面位置,刚开始准备用的cache:true,但是存在大大的问题就是新增和编辑后返回数据都不是最新的,无法重新刷新页面rel ...

  5. redis哈希缓存数据表

    redis哈希缓存数据表 REDIS HASH可以用来缓存数据表的数据,以后可以从REDIS内存数据库中读取数据. 从内存中取数,无疑是很快的. var FRedis: IRedisClient; F ...

  6. APP缓存数据线程安全问题

    问题 一般一个 iOS APP 做的事就是:请求数据->保存数据->展示数据,一般用 Sqlite 作为持久存储层,保存从网络拉取的数据,下次读取可以直接从 Sqlite DB 读取.我们 ...

  7. 除了用作缓存数据,Redis还可以做这些

    Redis应该说是目前最受欢迎的NoSQL数据库之一了.Redis通常被作为缓存组件,用作缓存数据.不过,除了可以缓存数据,其实Redis可以做的事还有很多.下面列举几例,供大家参考. 1.最新列表 ...

  8. 【C#】缓存数据

    namespace WpfCopy.Controls { public class CacheFileEventArgs : EventArgs { public bool IsFaulted { g ...

  9. 【转】数据存储——APP 缓存数据线程安全问题探讨

    http://blog.cnbang.net/tech/3262/ 问题 一般一个 iOS APP 做的事就是:请求数据->保存数据->展示数据,一般用 Sqlite 作为持久存储层,保存 ...

随机推荐

  1. etcd集群安装部署

    1. 集群架构 由于我们只有两个机房,所以选择的是以上图中所示的数据同步方案, 通过做镜像的方式保证两个集群的数据实时同步. 整体架构如上图所示, 整个全局元数据中心包括两套集群,廊坊集群和马驹桥集群 ...

  2. T-SQL with关键字 with as 递归循环表

    )SET @OrgId = N'901205CA-6C22-4EE7-AE4B-96CC7165D07F'; WITH Childs AS ( SELECT * FROM HROrgRelation ...

  3. String trim 坑 对于ascii码为160的去不掉

    大家在使用string   的trim去除空格的时候,要注意一个坑呀,对于ascii码为160的去不掉 import java.util.Arrays; /** * Created by bjchen ...

  4. 解决: ./netapp.bin: error while loading shared libraries: libcaffe.so.1.0.0: cannot open shared object file: No such file or directory 运行时报错(caffe)

    caffe安装好后lib没有配置到/usr/lib或/usr/local/lib中,需手动配置: export LD_LIBRARY_PATH=/path_to_your_caffe/build/li ...

  5. 洛谷 P4451 [国家集训队]整数的lqp拆分

    洛谷 这个题目是黑题,本来想打表的,但是表调不出来(我逊毙了)! 然后随便打了一个递推,凑出了样例, 竟然. 竟然.. 竟然... A了!!!!!!! 直接:\(f[i]=f[i-1]*2+f[i-2 ...

  6. What are the top 10 things that we should be informed about in life

    1.Realize that nobody cares, and if they do, you shouldn't care that they care. Got a new car? Nobod ...

  7. mysql-5.6.22的安装步骤

    一.环境与下载地址: 1.系统下载地址: http://mirrors.sohu.com/centos/6.6/isos/x86_64/CentOS-6.6-x86_64-bin-DVD1.iso 2 ...

  8. 用python的turtle画分形树

    由于分形树具有对称性,自相似性,所以我们可以用递归来完成绘制.只要确定开始树枝长.每层树枝的减短长度和树枝分叉的角度,我们就可以把分形树画出来啦!! 代码如下: # -*- coding: utf-8 ...

  9. 快速排序算法Java版

    网上关于快速排序的算法原理和算法实现都比较多,不过java是实现并不多,而且部分实现很难理解,和思路有点不搭调.所以整理了这篇文章.如果有不妥之处还请建议.首先先复习一些基础.    1.算法概念. ...

  10. Java并发(6):concurrent包中的Copy-On-Write容器

    一. concurrent包介绍 在JDK1.5之前,Java中要进行业务并发时,通常需要有程序员独立完成代码实现,而当针对高质量Java多线程并发程序设计时,为防止死蹦等现象的出现,比如使用java ...