读jQuery之六 缓存数据功能介绍


Posted in Javascript onJune 21, 2011

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

<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代码片段
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对象的属性名。
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。
<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
// 为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对象。举例说明
var myObj = {}; 
$.data(myObj, 'name', 'jack'); 
console.log(myObj);

myObj的结构如下
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。举例说明
<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之六 缓存数据功能介绍

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

// 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方法。
但如果你刻意要破坏,那么还是可以做的。如下
<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
zChain-0.6.js

Javascript 相关文章推荐
javascript 节点排序 2
Jan 31 Javascript
GRID拖拽行的实例代码
Jul 18 Javascript
window.onload绑定多个事件的两种解决方案
May 15 Javascript
微信小程序 开发工具快捷键整理
Oct 31 Javascript
BootStrap表单验证 FormValidation 调整反馈图标位置的实例代码
May 17 Javascript
Javascript中prototype与__proto__的关系详解
Mar 11 Javascript
从vue源码看props的用法
Jan 09 Javascript
微信小程序实现下拉刷新动画
Jun 21 Javascript
关于vue路由缓存清除在main.js中的设置
Nov 06 Javascript
解决vue+ element ui 表单验证有值但验证失败问题
Jan 16 Javascript
Javascript新手入门之字符串拼接与变量的应用
Dec 03 Javascript
解决vue $http的get和post请求跨域问题
Jun 07 Vue.js
将HTMLCollection/NodeList/伪数组转换成数组的实现方法
Jun 20 #Javascript
读jQuery之五(取DOM元素)
Jun 20 #Javascript
读jQuery之四(优雅的迭代)
Jun 20 #Javascript
火狐4、谷歌12不支持Jquery Validator的解决方法分享
Jun 20 #Javascript
合并table相同单元格的jquery插件分享(很精简)
Jun 20 #Javascript
functional继承模式 摘自javascript:the good parts
Jun 20 #Javascript
jQuery数组处理方法汇总
Jun 20 #Javascript
You might like
谏山创故乡大分县日田市水坝将设立《进击的巨人》立艾伦、三笠以及阿尔敏的铜像!
2020/03/06 日漫
社区(php&amp;&amp;mysql)四
2006/10/09 PHP
php ob_flush,flush在ie中缓冲无效的解决方法
2010/05/09 PHP
PHP迭代器和生成器用法实例分析
2019/09/28 PHP
深入分析js中的constructor和prototype
2012/04/07 Javascript
node.js中的console.assert方法使用说明
2014/12/10 Javascript
pace.js页面加载进度条插件
2015/09/29 Javascript
js实现select下拉框菜单
2015/12/08 Javascript
jQuery form插件之ajaxForm()和ajaxSubmit()的可选参数项对象
2016/01/23 Javascript
神奇!js+CSS+DIV实现文字颜色渐变效果
2016/03/16 Javascript
仅9张思维导图帮你轻松学习Javascript 就这么简单
2016/06/01 Javascript
Bootstrap框架的学习教程详解(二)
2016/10/18 Javascript
jQuery仿写百度百科的目录树
2017/01/03 Javascript
利用Vue.js框架实现火车票查询系统(附源码)
2017/02/27 Javascript
React Native实现进度条弹框的示例代码
2017/07/17 Javascript
JS使用正则表达式获取小括号、中括号及花括号内容的方法示例
2018/06/01 Javascript
使用 Vue cli 3.0 构建自定义组件库的方法
2019/04/30 Javascript
JS函数基本定义与用法示例
2020/01/15 Javascript
JS实现网站楼层导航效果代码实例
2020/06/16 Javascript
[01:33]一分钟玩转DOTA2第三弹:DOTA2&DotA快捷操作大对比
2014/06/04 DOTA
Python中类的创建和实例化操作示例
2019/02/27 Python
python django框架中使用FastDFS分布式文件系统的安装方法
2019/06/10 Python
python psutil模块使用方法解析
2019/08/01 Python
pycharm创建scrapy项目教程及遇到的坑解析
2019/08/15 Python
pytorch:torch.mm()和torch.matmul()的使用
2019/12/27 Python
Matplotlib.pyplot 三维绘图的实现示例
2020/07/28 Python
Python .py生成.pyd文件并打包.exe 的注意事项说明
2021/03/04 Python
html5拖曳操作 HTML5实现网页元素的拖放操作
2013/01/02 HTML / CSS
MAC彩妆英国官网:M·A·C UK
2018/05/30 全球购物
欧洲当代手工玻璃和瓷器的领先品牌:LSA International
2018/06/03 全球购物
DeinDesign德国:设计自己的手机壳
2019/12/14 全球购物
结婚典礼证婚词
2014/01/08 职场文书
条幅标语大全
2014/06/20 职场文书
鸡毛信观后感
2015/06/11 职场文书
2016元旦晚会主持词开场白和结束语
2015/12/04 职场文书
win11自动弹出虚拟键盘怎么关闭? Win11关闭虚拟键盘的技巧
2023/01/09 数码科技