利用原生JS实现data方法示例代码
前言
在开发中经常会在DOM上存储一些自定义数据,我们可以通过setAttribute方法来实现。但是当数据为引用类型时,存储后的数据却无效。这里将用原生的JS对data方法进行实现。
使用setAttribute:
vartestData=document.querySeletor('#test-data');
testData.setAttribute('baukh',{a:1,b:2})//执行后DOM节点变化为可以从上面的代码中看出,存进去的是个Object,取出来的是Object.toString()所产出的字符串。
分析
在JS经典类库-jQuery中存在data方法是通过jQuery.cache的方式进行数据存储,那么还有没有其它方法可以实现?
由于使用场景不同,我想实现的方式是将数据直接存储到DOM节点上,以达到使用时更方便简捷的目的。
那如何存储?变量testData存储的是通过document.querySeletor('#test-data')获取到的Element,而Element是Object的一个实例。通过[testDatainstanceofObject]可以进行验证。
那么一切都简易了,即然是Object类型,那么就可以随意的增删自定义属性。
通过在Element的原型上增加data方法来实现DOM扩展
Element.prototype.data=function(key,value){
var_this=this,
_dataName='testData',//存储至DOM上的对象标记,这里只是测试用名
_data={};
//未指定参数,返回全部
if(typeofkey==='undefined'&&typeofvalue==='undefined'){
return_this[_dataName];
}
//setter
if(typeof(value)!=='undefined'){
//存储值类型为字符或数字时,使用attr执行
var_type=typeof(value);
if(_type==='string'||_type==='number'){
_this.setAttribute(key,value);
}
_data=_this[_dataName]||{};
_data[key]=value;
_this[_dataName]=_data;
returnthis;
}
//getter
else{
_data=_this[_dataName]||{};
return_data[key]||_this.getAttribute(key);
}
};
这里来试一下:
vartestData=document.querySelector('#test-data');
//字符串类型测试
testData.data('name','baukh');
console.log(testData.data('name'));//=>'baukh'
//对象类型测试
testData.data('info',{'name':'baukh','age':27});
console.log(testData.data('info'));//=>Object{name:"baukh",age:27}
解决NodeList存储
现在还有一个问题,通过Element.prototype绑定的方法只支持Element类生效,而对NodeList类并无效果.
可以通过下面这些代码进行效果测试:
vartestDataList=document.querySelectorAll('.test-data-list');//获取的为NodeList而非Element
testDataList.data('name','baukh');//UncaughtTypeError:testDataList.dataisnotafunction
这肯定不是想要的结果,那么NodeList类就需要如下处理:
NodeList.prototype.data=function(key,value){
//setter
if(typeof(value)!=='undefined'){
[].forEach.call(this,function(element,index){
element.data(key,value);
});
returnthis;
}
//getter
else{
returnthis[0].data(key,value);//getter将返回第一个
}
};
来测试下NodeList类的data实现:
vartestDataList=document.querySelectorAll('.test-data-list');//获取的为NodeList而非Element
testDataList.data('name','baukh');//UncaughtTypeError:testDataList.dataisnotafunction
//字符串类型测试
testDataList.data('name','baukh');
console.log(testDataList.data('name'));//=>'baukh'
//对象类型测试
testDataList.data('info',{'name':'baukh','age':27});
console.log(testDataList.data('info'));//=>Object{name:"baukh",age:27}
这样就功能上就完成了.
当然也可以将NodeList与Element进行互换,具体情况具体考虑.
很简单不是吗?
顺带说一下,Array类型的数据,也可以增加自定义属性。
varar=[1,2,3];
console.log(arinstanceofObject);//true能添加自定义属性的原因就在这里,Array也是Object的实例。
ar.test1={a:1,b:2};
console.log(ar);//[1,2,3,test1:Object]
console.log(ar.test1);//Object{a:1,b:2}
随笔一行
这是前端最好的时代,这也是前端最坏的时代。众多前端框架满天飞,随着jQuery在前端行业的慢慢弱化,总是会有一种斯人远去,何者慰籍的感觉。互勉吧,各位。
另推荐个表格组件gridManager
总结
以上就是这篇文章的全部内容了,希望本文的内容对大家的学习或者工作具有一定的参考学习价值,谢谢大家对毛票票的支持。