You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
$.fn.data=function(name,value){returnvalue===undefined ?
// set multiple values via object$.isPlainObject(name) ?
this.each(function(i,node){$.each(name,function(key,value){setData(node,key,value)})}) :
// get value from first element(0inthis ? getData(this[0],name) : undefined) :
// set value on all elementsthis.each(function(){setData(this,name,value)})}
// Read all "data-*" attributes from a nodefunctionattributeData(node){varstore={}$.each(node.attributes||emptyArray,function(i,attr){if(attr.name.indexOf('data-')==0)store[camelize(attr.name.replace('data-',''))]=$.zepto.deserializeValue(attr.value)})returnstore}
前言
原文链接
源码仓库
原理
看一下上面那张图。简单地理解就是
exp(Zepto1507010934916)
属性,其对应的值是1,2,3整数数字,dom元素就是通过1,2,3数字索引和大对象data关联起来
对于DOM自定义数据的增删改查就是在对数字索引对应的对象进行操作。
$.fn.data
例子
基本用法大家肯定很熟悉,需要注意的地方是,我们也可以直接获取定义在html标签上以
data-
为前缀的属性。接下来我们就直接看源码实现啦源码
通过上面的例子我们知道,设置数据的时候可以单个属性设置,也可以多个属性(传递一个对象)一起设置。大量使用三目运算是Zepto一贯的风格。我们来拆解一下这段代码。
通过遍历匹配元素,并调用setData方法传入元素,要设置的数据的key和value。
此时走的是这段代码
还是遍历当前匹配元素,并且遍历传进的对象
name
,到底层还是调用setData
方法一个个属性进行设置。通过判断当前是否有匹配的元素,如果有则是调用
getData
方法,并传入匹配元素集合中的第一个元素,以及要获取的数据name属性。如果没有匹配元素,就直接返回undefined了。总体逻辑还是挺清晰的。接下来我们主要需要弄清楚上面用到的几个函数
setData
,getData
。以及解释一下data模块初始定义的几个变量各变量解释如下
setData
exp
是类似Zepto1507004986420
的字符串,$.uuid初始值是0,首先会尝试去读取元素身上的exp属性,元素没有该属性就为该元素设置exp
属性。并去
data
大对象中读取id(1, 2, 3...)
属性,当然了如果data对象中没有读取到,就通过调用attributeData
函数先获取node
节点所有以data-
为前缀的自定义属性,并将其赋值。现在自定义属性的集合已经有了,先判断name是否是个undefined,不是就往store上添加name属性。
最后函数调用之后会返回整个数据对象store。
attributeData
获取元素以
data-
为前缀的自定义属性的集合我们先来看一下node.attributes mdn是个啥
例子
得到的数据如上图所示,接下来我们再回到
attributeData
函数的源码分析通过判断
ele.attributes
拿到的集合中,是否是以data-
开头的属性,如果是就往store对象中添加驼峰化后的该属性,并且序列化之后的attr.value
作为该属性的值。最后将store对象返回。getData
实现思路还是首先去读取
setData
时候添加在node节点上的id,然后以该id为key去data中查找。如果name没有传,此时直接返回整个store,当然如果store也没有找到,就返回调用setData
后返回的该元素的自定义属性的集合。当store存在时,先判断name属性在store中存在与否,存在便直接返回相应的属性,否则对传入的name进行驼峰化之后再判断在store中是否存在,存在即返回对应的属性。也就是说你传入的name为
min-age
或者minAge
得到的是一样的值。最后如果在数据缓存中还没有找到属性name,就调用dataAttr函数,去直接查找元素身上的相关属性。
removeData
可以添加或者更新数据自然也就可以移除数据了,先看下例子
例子
我们可以指定删除单个属性,也可以通过空格隔开删除多个属性,也可以传入一个要删除的属性数组,甚至当你什么都不传的时候,原先设置在该元素身上的data会被全部清空
源码
首先传进来的names是字符串的情况下,先转化成数组,接着就是对当前匹配的元素集合进行遍历,逐个删除元素对应的缓存的数据。
当查找到store的时候对转化后的names或者store进行遍历,如果是自己指定要删除的属性,先驼峰化一下,再用delete删除,否则全部清空则直接delete store中的key
$.data
定义在$函数身上的静态方法,底层还是调用的实例方法.data。
$.hasData
同样定义在$函数身上的静态方法,原理就是拿着
elem
身上的id,去data中查找是否有与之关联的数据对象,如果找到了并且不是一个空对象,便返回true,否则没有找到或者是空对象都是返回falseremove, empty
结尾
文章记录
data模块
form模块
zepto模块
event模块
ajax模块
The text was updated successfully, but these errors were encountered: