利用原生JS实现data方法示例代码


Posted in Javascript onMay 28, 2019

前言

在开发中经常会在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类并无效果.

可以通过下面这些代码进行效果测试:

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 在前端行业的慢慢弱化,总是会有一种斯人远去,何者慰籍的感觉。互勉吧,各位。

另推荐个表格组件gridManager

总结

以上就是这篇文章的全部内容了,希望本文的内容对大家的学习或者工作具有一定的参考学习价值,谢谢大家对三水点靠木的支持。

Javascript 相关文章推荐
Javascript 验证上传图片大小[客户端]
Aug 01 Javascript
jQuery中:image选择器用法实例
Jan 03 Javascript
JS数组合并push与concat区别分析
Dec 17 Javascript
详解Jquery实现ready和bind事件
Apr 14 Javascript
详解JavaScript对象类型
Jun 16 Javascript
原生js实现class的添加和删除简单代码
Jul 12 Javascript
node.js实现快速截图
Aug 27 Javascript
第一个Vue插件从封装到发布
Nov 22 Javascript
使用vue完成微信公众号网页小记(推荐)
Apr 28 Javascript
Vue 利用指令实现禁止反复发送请求的两种方法
Sep 15 Javascript
JS扁平化输出数组的2种方法解析
Sep 17 Javascript
vue获取data数据改变前后的值方法
Nov 07 Javascript
php结合js实现多条件组合查询
May 28 #Javascript
vue实现前台列表数据过滤搜索、分页效果
May 28 #Javascript
js 将线性数据转为树形的示例代码
May 28 #Javascript
React中使用外部样式的3种方式(小结)
May 28 #Javascript
vue实现多条件和模糊搜索功能
May 28 #Javascript
vue实现路由切换改变title功能
May 28 #Javascript
Vue 无限滚动加载指令实现方法
May 28 #Javascript
You might like
PHP+javascript模拟Matrix画面
2006/10/09 PHP
PHP使用zlib扩展实现GZIP压缩输出的方法详解
2018/04/09 PHP
PHP从零开始打造自己的MVC框架之路由类实现方法分析
2019/06/03 PHP
jQuery 图像裁剪插件Jcrop的简单使用
2009/05/22 Javascript
js实现tab切换效果实例
2015/09/16 Javascript
JavaScript encodeURI 和encodeURIComponent
2015/12/04 Javascript
Bootstrap零基础入门教程(二)
2016/07/18 Javascript
防止Node.js中错误导致进程阻塞的办法
2016/08/11 Javascript
正则中的回溯定义与用法分析【JS与java实现】
2016/12/27 Javascript
非常实用的vue导航钩子
2017/03/20 Javascript
vue实现的仿淘宝购物车功能详解
2019/01/27 Javascript
微信小程序调用天气接口并且渲染在页面过程详解
2019/06/24 Javascript
vue 子组件修改data或调用操作
2020/08/07 Javascript
Python中zip()函数用法实例教程
2014/07/31 Python
python使用chardet判断字符串编码的方法
2015/03/13 Python
python在Windows8下获取本机ip地址的方法
2015/03/14 Python
Python运算符重载用法实例分析
2015/06/01 Python
对python中Librosa的mfcc步骤详解
2019/01/09 Python
详解Python并发编程之从性能角度来初探并发编程
2019/08/23 Python
.dcm格式文件软件读取及python处理详解
2020/01/16 Python
Python操作注册表详细步骤介绍
2020/02/05 Python
python实现一次性封装多条sql语句(begin end)
2020/06/06 Python
详解BeautifulSoup获取特定标签下内容的方法
2020/12/07 Python
如何用python 操作zookeeper
2020/12/28 Python
全网最详细的PyCharm+Anaconda的安装过程图解
2021/01/25 Python
美国成衣女装品牌:CHICO’S
2016/09/19 全球购物
英国标志性生活方式品牌:Skinnydip London
2019/12/15 全球购物
我能否用void** 指针作为参数, 使函数按引用接受一般指针
2013/02/16 面试题
班主任工作经验材料
2014/02/02 职场文书
文秘档案管理岗位职责
2014/03/06 职场文书
经济职业学院毕业生自荐书
2014/03/17 职场文书
2015年幼儿园教育教学工作总结
2015/05/25 职场文书
2019年消防宣传标语集锦
2019/11/21 职场文书
深度学习tensorflow基础mnist
2021/04/14 Python
浅谈PHP7中的一些小技巧
2021/05/29 PHP
Nginx配置根据url参数重定向
2022/04/11 Servers