利用原生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
总结
以上就是这篇文章的全部内容了,希望本文的内容对大家的学习或者工作具有一定的参考学习价值,谢谢大家对毛票票的支持。