利用原生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 相关文章推荐
学习ExtJS table布局
Oct 08 Javascript
动态创建script在IE中缓存js文件时导致编码的解决方法
May 04 Javascript
jQuery实现的图片分组切换焦点图插件
Jan 06 Javascript
jQuery处理json数据返回数组和输出的方法
Mar 11 Javascript
JavaScript中继承用法实例分析
May 16 Javascript
浅谈Node.js:fs文件系统模块
Dec 08 Javascript
jQuery中的一些小技巧
Jan 18 Javascript
JS获取一个表单字段中多条数据并转化为json格式
Oct 17 Javascript
浅谈如何优雅处理JavaScript异步错误
Nov 12 Javascript
微信小程序修改checkbox的样式代码实例
Jan 21 Javascript
js实现百度登录窗口拖拽效果
Mar 19 Javascript
vant中的toast层级改变操作
Nov 04 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 5.3和PHP 5.4出现FastCGI Error解决方法
2015/02/12 PHP
简单解决微信文章图片防盗链问题
2016/12/17 PHP
ecshop添加菜单及权限分配问题
2017/11/21 PHP
php中文语义分析实现方法示例
2019/09/28 PHP
表单验证的完整应用案例探讨
2013/03/29 Javascript
JS来动态的修改url实现对url的增删查改
2014/09/05 Javascript
浅谈jQuery中对象遍历.eq().first().last().slice()方法
2014/11/26 Javascript
jQuery中parent()方法用法实例
2015/01/07 Javascript
Bootstrap 3的box-sizing样式导致UEditor控件的图片无法正常缩放的解决方案
2016/09/15 Javascript
Node.js安装配置图文教程
2017/05/10 Javascript
jquery实现点击a链接,跳转之后,该a链接处显示背景色的方法
2018/01/18 jQuery
浅析vue.js数组的变异方法
2018/06/30 Javascript
koa-router源码学习小结
2018/09/07 Javascript
微信小程序 checkbox使用实例解析
2019/09/09 Javascript
Vue 自定义指令功能完整实例
2019/09/17 Javascript
layui文件上传控件带更改后数据传值的方法
2019/09/23 Javascript
vue计算属性无法监听到数组内部变化的解决方案
2019/11/06 Javascript
微信小程序canvas截取任意形状的实现代码
2020/01/13 Javascript
微信小程序间使用navigator跳转传值问题实例分析
2020/03/27 Javascript
[52:15]2014 DOTA2国际邀请赛中国区预选赛5.21 HGT VS LGD-GAMING
2014/05/23 DOTA
python2.7无法使用pip的解决方法(安装easy_install)
2018/04/03 Python
python实现类之间的方法互相调用
2018/04/29 Python
python内存监控工具memory_profiler和guppy的用法详解
2019/07/29 Python
Python绘图实现显示中文
2019/12/04 Python
基于Python实现扑克牌面试题
2019/12/11 Python
python两种注释用法的示例
2020/10/09 Python
思想纪律作风整顿剖析材料
2014/10/11 职场文书
检讨书1000字
2014/10/11 职场文书
后勤工作个人总结
2015/02/28 职场文书
工作自我推荐信范文
2015/03/25 职场文书
采购员岗位职责范本
2015/04/07 职场文书
清洁工工作总结
2015/08/11 职场文书
学雷锋主题班会教案
2015/08/13 职场文书
入党申请书怎么写?
2019/06/11 职场文书
MySQL 自动填充 create_time 和 update_time
2022/05/20 MySQL
win10忘记pin密码登录不了怎么办?win10忘记pin密码登不进去的解决方法
2022/07/07 数码科技