利用原生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 相关文章推荐
js 代码集(学习js的朋友可以看下)
Jul 22 Javascript
JAVASCRIPT车架号识别/验证函数代码 汽车车架号验证程序
Jan 08 Javascript
jQuery如何防止这种冒泡事件发生
Feb 27 Javascript
JS+CSS实现美化的下拉列表框效果
Aug 11 Javascript
常用Javascript函数与原型功能收藏(必看篇)
Oct 09 Javascript
微信小程序 wxapp内容组件 icon详细介绍
Oct 31 Javascript
js放大镜放大购物图片效果
Jan 18 Javascript
angular中实现li或者某个元素点击变色的两种方法
Jul 27 Javascript
C#实现将一个字符转换为整数
Dec 12 Javascript
vue 自定义指令自动获取文本框焦点的方法
Aug 25 Javascript
微信小程序实现折线图的示例代码
Jun 07 Javascript
es6函数name属性功能与用法实例分析
Apr 18 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+MYSQL的文章管理系统(二)
2006/10/09 PHP
php数组函数序列之array_key_exists() - 查找数组键名是否存在
2011/10/29 PHP
一个比较不错的PHP日历类分享
2014/11/18 PHP
window.location.href = window.location.href 跳转无反应 a超链接onclick事件写法
2013/08/21 Javascript
js中settimeout方法加参数的使用实例
2014/02/27 Javascript
JavaScript中提前声明变量或函数例子
2014/11/12 Javascript
深入理解React中何时使用箭头函数
2017/08/23 Javascript
vue 组件 全局注册和局部注册的实现
2018/02/28 Javascript
解决layui中的form表单与button的点击事件冲突问题
2018/08/15 Javascript
JS加密插件CryptoJS实现的Base64加密示例
2020/08/16 Javascript
javascript的delete运算符知识点总结
2019/11/19 Javascript
Node.js创建一个Express服务的方法详解
2020/01/06 Javascript
jQuery实现滑动开关效果
2020/08/02 jQuery
[30:00]完美世界DOTA2联赛PWL S2 Rebirth vs LBZS 第二场 11.28
2020/12/01 DOTA
python批量提交沙箱问题实例
2014/10/08 Python
python制作最美应用的爬虫
2015/10/28 Python
浅谈Python 集合(set)类型的操作——并交差
2016/06/30 Python
windows下 兼容Python2和Python3的解决方法
2018/12/05 Python
Django CBV与FBV原理及实例详解
2019/08/12 Python
python 实现保存最新的三份文件,其余的都删掉
2019/12/22 Python
pandas分组聚合详解
2020/04/10 Python
HTML5+CSS3:3D展示商品信息示例
2017/01/03 HTML / CSS
Bealls Florida百货商店:生活服饰、家居装饰和鞋子
2018/02/23 全球购物
全球高级音频和视频专家:HiDef Lifestyle
2019/08/02 全球购物
科颜氏香港官方网店:Kiehl’s香港
2021/03/07 全球购物
如何开发安全的AJAX应用
2014/03/26 面试题
应届毕业生专业个人求职自荐信格式
2013/11/20 职场文书
技术经理的自我评价范文
2013/12/03 职场文书
初三班主任寄语大全
2014/04/04 职场文书
广播节目策划方案
2014/05/23 职场文书
无财产无子女离婚协议书范文
2014/09/14 职场文书
教师个人考察材料
2014/12/16 职场文书
公务员考察材料
2014/12/23 职场文书
幼儿园老师工作总结2015
2015/05/22 职场文书
2007年老电脑安装win11会怎么样? 网友实测win11在老电脑运行良好
2021/11/21 数码科技
解决vue-router的beforeRouteUpdate不能触发
2022/04/14 Vue.js