利用原生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 相关文章推荐
元素绑定click点击事件方法
Jun 08 Javascript
AngularJS实现表单手动验证和表单自动验证
Dec 09 Javascript
javascript实现html页面之间参数传递的四种方法实例分析
Dec 15 Javascript
检查表单元素的值是否为空的实例代码
Jun 16 Javascript
微信小程序 textarea 详解及简单使用方法
Dec 05 Javascript
原生JS改变透明度实现轮播效果
Mar 24 Javascript
js实现扫雷小程序的示例代码
Sep 27 Javascript
微信小程序登录态和检验注册过没的app.js写法
May 22 Javascript
js变量值传到php过程详解 将php解析成数据
Jun 26 Javascript
JS轮播图的实现方法2
Aug 25 Javascript
解决Vue-cli3没有vue.config.js文件夹及配置vue项目域名的问题
Dec 04 Vue.js
vue+vant 上传图片需要注意的地方
Jan 03 Vue.js
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多线程之内部多线程实例分析
2015/03/09 PHP
PHP基于SMTP协议实现邮件发送实例代码
2017/04/27 PHP
PHP实现压缩图片尺寸并转为jpg格式的方法示例
2018/05/10 PHP
不一样的文字闪烁 轮番闪烁
2009/11/11 Javascript
关于js datetime的那点事
2011/11/15 Javascript
JavaScript中的eval()函数详解
2013/08/22 Javascript
easyUI实现(alert)提示框自动关闭的实例代码
2016/11/07 Javascript
js 数字、字符串、布尔值的转换方法(必看)
2017/04/07 Javascript
vue组件中点击按钮后修改输入框的状态实例代码
2017/04/14 Javascript
微信小程序倒计时功能实现代码
2017/11/09 Javascript
Gulp实现静态网页模块化的方法详解
2018/01/09 Javascript
Js面试算法详解
2018/04/08 Javascript
JavaScript常见JSON操作实例分析
2018/08/08 Javascript
vue实现随机验证码功能的实例代码
2019/04/30 Javascript
Vue2.0使用嵌套路由实现页面内容切换/公用一级菜单控制页面内容切换(推荐)
2019/05/08 Javascript
基于webpack4+vue-cli3项目实现换肤功能
2019/07/17 Javascript
jquery.pager.js实现分页效果
2019/07/29 jQuery
Ant-design-vue Table组件customRow属性的使用说明
2020/10/28 Javascript
[37:45]2014 DOTA2国际邀请赛中国区预选赛5.21 DT VS Orenda
2014/05/22 DOTA
python实现简单登陆流程的方法
2018/04/22 Python
python统计多维数组的行数和列数实例
2018/06/23 Python
python解决字符串倒序输出的问题
2018/06/25 Python
Python函数装饰器实现方法详解
2018/12/22 Python
python修改txt文件中的某一项方法
2018/12/29 Python
Canvas 文字碰撞检测并抽稀的方法
2019/05/27 HTML / CSS
大一新生军训时的自我评价分享
2013/12/05 职场文书
电脑饰品店的创业计划书
2014/01/21 职场文书
化学系大学生自荐信范文
2014/03/01 职场文书
文明班集体申报材料
2014/05/23 职场文书
财务人员个人工作总结
2015/02/27 职场文书
工作试用期自我评价
2015/03/10 职场文书
2015年体育部工作总结
2015/04/02 职场文书
2015年高校教师个人工作总结
2015/05/25 职场文书
2016十一国庆节慰问信
2015/12/01 职场文书
通知怎么写?
2019/04/17 职场文书
避坑之 JavaScript 中的toFixed()和正则表达式
2022/04/19 Javascript