利用原生JS实现data方法示例代码
前言
在开发中经常会在DOM上存储一些自定义数据,我们可以通过setAttribute方法来实现。当数据为引用类型时,存储后的数据却无效。这里将用原生的JS对data方法进行实现。
使用setAttribute:
<div id="test-data"></div> <p class="test-data-list"></p> <p class="test-data-list"></p> <p class="test-data-list"></p> <p class="test-data-list"></p>
var testData = document.querySeletor('#test-data'); testData.setAttribute('baukh', {a:1,b:2})// 执行后DOM节点变化为<div baukh="[object Object]"></div> testData.getAttribute('baukh'); // => "[object Object]"
可以从上面的代码中看出,存进去的是个Object,取出来的是Object.toString()
所产出的字符串。
分析
在JS经典类库-jQuery中存在data方法是通过jQuery.cache的方式进行数据存储,那么还有没有其它方法可以实现?
由于使用场景不同,我想实现的方式是将数据直接存储到DOM节点上,以达到使用时更方便简捷的目的。
那如何存储? 变量testData存储的是通过document.querySeletor('#test-data')
获取到的Element,而Element是Object的一个实例。通过[testData instanceof Object]
可以进行验证。
那么一切都简易了,即然是Object类型,那么就可以随意的增删自定义属性。
通过在Element的原型上增加data方法来实现DOM扩展
Element.prototype.data = function(key, value){ var _this = this, _dataName = 'testData', // 存储至DOM上的对象标记, 这里只是测试用名 _data = {}; // 未指定参数,返回全部 if(typeof key === 'undefined' && typeof value === '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; return this; } // getter else{ _data = _this[_dataName] || {}; return _data[key] || _this.getAttribute(key); } };
这里来试一下:
var testData = 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类并无效果.
可以通过狼蚁网站SEO优化这些代码进行效果测试:
var testDataList = document.querySelectorAll('.test-data-list'); // 获取的为NodeList 而非 Element testDataList.data('name', 'baukh'); // Uncaught TypeError: testDataList.data is not a function
这肯定不是想要的结果, 那么NodeList类就需要如下处理:
NodeList.prototype.data = function (key, value) { // setter if(typeof(value) !== 'undefined'){ [].forEach.call(this, function (element, index) { element.data(key, value); }); return this; } // getter else{ return this[0].data(key, value); // getter 将返回第一个 } };
来测试下NodeList类的data实现:
var testDataList = document.querySelectorAll('.test-data-list'); // 获取的为NodeList 而非 Element testDataList.data('name', 'baukh'); // Uncaught TypeError: testDataList.data is not a function // 字符串类型测试 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类型的数据,也可以增加自定义属性。
var ar = [1,2,3]; console.log(ar instanceof Object); //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 在前端行业的慢慢弱化,总是会有一种斯人远去,何者慰籍的感觉。互勉吧,各位。
另推荐个表格组件
以上就是这篇文章的全部内容了,希望本文的内容对大家的学习或者工作具有一定的参考学习价值,谢谢大家对狼蚁SEO的支持。
编程语言
- 如何快速学会编程 如何快速学会ug编程
- 免费学编程的app 推荐12个免费学编程的好网站
- 电脑怎么编程:电脑怎么编程网咯游戏菜单图标
- 如何写代码新手教学 如何写代码新手教学手机
- 基础编程入门教程视频 基础编程入门教程视频华
- 编程演示:编程演示浦丰投针过程
- 乐高编程加盟 乐高积木编程加盟
- 跟我学plc编程 plc编程自学入门视频教程
- ug编程成航林总 ug编程实战视频
- 孩子学编程的好处和坏处
- 初学者学编程该从哪里开始 新手学编程从哪里入
- 慢走丝编程 慢走丝编程难学吗
- 国内十强少儿编程机构 中国少儿编程机构十强有
- 成人计算机速成培训班 成人计算机速成培训班办
- 孩子学编程网上课程哪家好 儿童学编程比较好的
- 代码编程教学入门软件 代码编程教程