JQuery data 接口是什么?

.data()

Store arbitrary data associated with the matched elements or return the value at the named data store for the first element in the set of matched elements.

  根据jquery官网介绍,data给存储DOM关联的数据, 设置数据是对$选取的所有JQuery对象, 获取数据是对$选取的所有对象的第一个对象的存储的数据。

  设置语法格式 --- 设置单个数据 .data( key, value )  设置一组数据 .data( obj )

  获取语法格式 --- 获取单个数据 .data( key)  设置所有数据 .data()

例子:

$( "body" ).data( "foo", 52 );
$( "body" ).data( "bar", { myType: "test", count: 40 } );
$( "body" ).data( { baz: [ 1, 2, 3 ] } );
$( "body" ).data( "foo" ); //
$( "body" ).data(); // { foo: 52, bar: { myType: "test", count: 40 }, baz: [ 1, 2, 3 ] }

为什么需要 data 接口?

  web前端JS编程不可避免地,需要频繁地与DOM对象打交道。 HTML标签负责文档的结构, JS负责文档的行为, CSS负责文档的样式, JS通过document.getElementById()等接口获取DOM对象, 除了操作DOM对象的样式和属性等,往往在行为逻辑上, 脚本需要记录与DOM对象相关的数据 或者 某种状态值, 如果在js中直接使用全局变量记录此值, 具有很大的缺点, 首先不能直观体现此数据与DOM对象的关系, 其次全局变量有可能会发生命名冲突。

  例如,一个进度条DOM对象, 需要记录进度百分比值, 可以将此数据使用data接口记录到DOM对象上。

data 接口代码分析- .data( key, value )  设置单个数据

1、 JQuery对象的原型fn函数集合,添加了data接口,此接口判断如果为设置数据, 即arguments.length>1, 表示具有两个参数, 则执行红色代码三行, 将需要设置的DOM对象和需要设置的key和value , 传入 JQuery对象的data接口。

JQuery对象的data接口又做了些什么?

jQuery.fn.extend({
data: function( key, value ) {
var i, name, data,
elem = this[0],
attrs = elem && elem.attributes; .....
return arguments.length > 1 ? // Sets one value
this.each(function() {
jQuery.data( this, key, value );
}) : // Gets one value
// Try to fetch any internally stored data first
elem ? dataAttr( elem, key, jQuery.data( elem, key ) ) : undefined;
},

2、 jQuery.data函数分析

调用internalData函数并返回此函数的返回值。

jQuery.extend({
cache: {},
......
data: function( elem, name, data ) {
return internalData( elem, name, data );
},

3、 internalData 函数分析

此函数的第四个入参pvt可以忽略,执行过程有下面几个关键点:

#1 对于DOM对象nodeType为 1, 则缓存cache被设置为JQuery.cache。 此缓存空间即为 每个DOM对象data数据存储空间。

#2  对于第一次使用data接口, 需要对DOM元素, 生成一个唯一的ID: id = deletedIds.pop() || jQuery.guid++;

#3  然后在缓存空间 JQuery.cache中, 按照ID为下表为此DOM元素分配一个子空间: cache[ id ] = {}

#4 将此DOM子空间记录为 thisCache = cache[ id ];

#5 为此DOM子空间再开辟明确的data子空间: thisCache.data = {}; 并将此data子空间记录为thisCache

#6 设置数据 : thisCache[ jQuery.camelCase( name ) ] = data;

function internalData( elem, name, data, pvt /* Internal Use Only */ ) {

............
var ret, thisCache,
internalKey = jQuery.expando, // We have to handle DOM nodes and JS objects differently because IE6-7
// can't GC object references properly across the DOM-JS boundary
isNode = elem.nodeType, // Only DOM nodes need the global jQuery cache; JS object data is
// attached directly to the object so GC can occur automatically
cache = isNode ? jQuery.cache : elem,
...........
if ( !id ) {
// Only DOM nodes need a new unique ID for each element since their data
// ends up in the global cache
if ( isNode ) {
id = elem[ internalKey ] = deletedIds.pop() || jQuery.guid++;
} else {
id = internalKey;
}
} if ( !cache[ id ] ) {
// Avoid exposing jQuery metadata on plain JS objects when the object
// is serialized using JSON.stringify
cache[ id ] = isNode ? {} : { toJSON: jQuery.noop };
} ............
thisCache = cache[ id ]; // jQuery data() is stored in a separate object inside the object's internal data
// cache in order to avoid key collisions between internal data and user-defined
// data.
if ( !pvt ) {
if ( !thisCache.data ) {
thisCache.data = {};
} thisCache = thisCache.data;
} if ( data !== undefined ) {
thisCache[ jQuery.camelCase( name ) ] = data;
}
...............
}

data 接口代码分析- .data( key)  获取单个数据

1、此接口判断如果为获取数据, 即arguments.length>1为false, 表示具有一个参数, 则返回 下面函数调用返回的结果: dataAttr( elem, key, jQuery.data( elem, key ) )

dataAttr又做了些什么?

jQuery.fn.extend({
data: function( key, value ) {
var i, name, data,
elem = this[0],
attrs = elem && elem.attributes; .....
return arguments.length > 1 ? // Sets one value
this.each(function() {
jQuery.data( this, key, value );
}) : // Gets one value
// Try to fetch any internally stored data first
elem ? dataAttr( elem, key, jQuery.data( elem, key ) ) : undefined;
},

2、 dataAttr 分析

查看注释, 此函数为 data不存在的情况下, 查HTML中 data-开头的相同属性值, 此处可以不用分析。

下面还是分析下下面函数调用执行, jQuery.data( elem, key )
function dataAttr( elem, key, data ) {
// If nothing was found internally, try to fetch any
// data from the HTML5 data-* attribute
if ( data === undefined && elem.nodeType === 1 ) {

3、 jQuery.data( elem, key ) 获取单个数据

调用internalData函数并返回此函数的返回值。

我们下面分析 internalData函数第三个参数 data为空的情况。

jQuery.extend({
cache: {},
......
data: function( elem, name, data ) {
return internalData( elem, name, data );
},

4、 internalData 函数分析

此函数的第四个入参pvt可以忽略:

可以看到,对于获取单个数据情况, 还是从 JQuery.cache[DOM-ID].data中查找, 即下面这一句:

ret = thisCache[ name ];
function internalData( elem, name, data, pvt /* Internal Use Only */ ) {
...............
var ret, thisCache,
internalKey = jQuery.expando, // We have to handle DOM nodes and JS objects differently because IE6-7
// can't GC object references properly across the DOM-JS boundary
isNode = elem.nodeType, // Only DOM nodes need the global jQuery cache; JS object data is
// attached directly to the object so GC can occur automatically
cache = isNode ? jQuery.cache : elem, // Only defining an ID for JS objects if its cache already exists allows
// the code to shortcut on the same path as a DOM node with no cache
id = isNode ? elem[ internalKey ] : elem[ internalKey ] && internalKey;

.................
thisCache = cache[ id ]; // jQuery data() is stored in a separate object inside the object's internal data
// cache in order to avoid key collisions between internal data and user-defined
// data.
if ( !pvt ) {
if ( !thisCache.data ) {
thisCache.data = {};
} thisCache = thisCache.data;
}
.................// Check for both converted-to-camel and non-converted data property names
// If a data property was specified
if ( typeof name === "string" ) { // First Try to find as-is property data
ret = thisCache[ name ]; // Test for null|undefined property data
if ( ret == null ) { // Try to find the camelCased property
ret = thisCache[ jQuery.camelCase( name ) ];
}
} else {
ret = thisCache;
} return ret;
}

JQuery data API实现代码分析的更多相关文章

  1. jQuery File Upload 插件 php代码分析

    jquery file upload php代码分析首先进入构造方法 __construct() 再进入 initialize()因为我是post方式传的数据  在进入initialize()中的po ...

  2. JQuery html API支持解析执行Javascript脚本功能实现-代码分析

    JQuery html用法(功能类似innerHTML) 开发中需要使用Ajax技术来更新页面局部区域, 使用的方法是ajax获取html代码段(字符串),然后将这个html代码段作为参数,传入目标D ...

  3. jQuery源码解读 - 数据缓存系统:jQuery.data

    jQuery在1.2后引入jQuery.data(数据缓存系统),主要的作用是让一组自定义的数据可以DOM元素相关联——浅显的说:就是让一个对象和一组数据一对一的关联. 一组和Element相关的数据 ...

  4. 转:jQuery.data

    原文地址:http://www.it165.net/pro/html/201404/11922.html 内存泄露 首先看看什么是内存泄露,这里直接拿来Aaron中的这部分来说明什么是内存泄露,内存泄 ...

  5. 完整全面的Java资源库(包括构建、操作、代码分析、编译器、数据库、社区等等)

    构建 这里搜集了用来构建应用程序的工具. Apache Maven:Maven使用声明进行构建并进行依赖管理,偏向于使用约定而不是配置进行构建.Maven优于Apache Ant.后者采用了一种过程化 ...

  6. jQuery源码解读-事件分析

    最原始的事件注册 addEventListener方法大家应该都很熟悉,它是Html元素注册事件最原始的方法.先看下addEventListener方法签名: element.addEventList ...

  7. AngularJS PhoneCat代码分析

    转载自:http://www.tuicool.com/articles/ym6Jfen AngularJS 官方网站提供了一个用于学习的示例项目:PhoneCat.这是一个Web应用,用户可以浏览一些 ...

  8. jquery datatables api (转)

    学习可参考:http://www.guoxk.com/node/jquery-datatables http://yuemeiqing2008-163-com.iteye.com/blog/20069 ...

  9. Hive metastore整体代码分析及详解

    从上一篇对Hive metastore表结构的简要分析中,我再根据数据设计的实体对象,再进行整个代码结构的总结.那么我们先打开metadata的目录,其目录结构: 可以看到,整个hivemeta的目录 ...

随机推荐

  1. Android LruCache(Picasso内存缓存)

    Cache保存一个强引用来限制内容数量,每当Item被访问的时候,此Item就会移动到队列的头部,当cache已满的时候加入新的item时,在队列尾部的item会被回收. 如果你cache的某个值需要 ...

  2. HDU-敌兵布阵

    Problem Description C国的死对头A国这段时间正在进行军事演习,所以C国间谍头子Derek和他手下Tidy又开始忙乎了.A国在海岸线沿直线布置了N个工兵营地,Derek和Tidy的任 ...

  3. SPFA算法

    SPFA算法 一.算法简介 SPFA(Shortest Path Faster Algorithm)算法是求单源最短路径的一种算法,它是Bellman-ford的队列优化,它是一种十分高效的最短路算法 ...

  4. RMQ问题之ST算法

    RMQ问题之ST算法 RMQ(Range Minimum/Maximum Query)问题,即区间最值问题.给你n个数,a1 , a2 , a3 , ... ,an,求出区间 [ l , r ]的最大 ...

  5. 【BZOJ1012】 【JSOI2008】最大数maxnumber

    Description 现在请求你维护一个数列,要求提供以下两种操作: 1. 查询操作.语法:Q L 功能:查询当前数列中末尾L个数中的最大的数,并输出这个数的值.限制:L不超过当前数列的长度. 2. ...

  6. xargs

    xargs的作用一般等同于大多数Unix shell中的反引号,但更加灵活易用,并可以正确处理输入中有空格等特殊字符的情况.对于经常产生大量输出的命令如find.locate和grep来说非常有用.

  7. odoo XMLRPC 新库 OdooRPC 尝鲜

    无意中发现了python居然有了OdoRPC的库,惊喜之下赶紧尝试一番,比XMLRPC简洁了不少,机制看样子是利用的JsonRPC. #原文出自KevinKong的博客http://www.cnblo ...

  8. div居中

    <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/ ...

  9. 使用webbench对不同的web服务器进行压力测试

    1.webbench在linux下的安装步骤,如果安装过程失败,请检查当前用户的执行权限,如果报找不到某个目录的错,请自行创建指定的目录: #wget http://home.tiscali.cz/~ ...

  10. cocos2d-x渲染流程

    Cocos2Dx之渲染流程 发表于8个月前(2014-08-08 22:46)   阅读(3762) | 评论(2) 17人收藏此文章, 我要收藏 赞2 如何快速提高你的薪资?-实力拍“跳槽吧兄弟”梦 ...