利用原生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 相关文章推荐
firefox firebug中文入门教程 脚本之家新年特别版
Jan 02 Javascript
Jquery插件之多图片异步上传
Oct 20 Javascript
js局部刷新页面时间具体实现
Jul 04 Javascript
node.js中的fs.ftruncate方法使用说明
Dec 15 Javascript
Markdown与Bootstrap相结合实现图片自适应属性
May 04 Javascript
Bootstrap Modal遮罩弹出层代码分享
Nov 21 Javascript
smartupload实现文件上传时获取表单数据(推荐)
Dec 12 Javascript
利用策略模式与装饰模式扩展JavaScript表单验证功能
Feb 14 Javascript
jQuery zTree插件使用简单教程
Aug 16 jQuery
通过vue刷新左侧菜单栏操作
Aug 06 Javascript
vue+elementui通用弹窗的实现(新增+编辑)
Jan 07 Vue.js
一百多行代码实现react拖拽hooks
Mar 23 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
这部番真是良心,画质好到像风景区,剧情让人跟着小公会热血沸腾
2020/03/10 日漫
Zend Framework中的简单工厂模式 图文
2012/07/10 PHP
ci检测是ajax还是页面post提交数据的方法
2014/11/10 PHP
phpStorm+XDebug+chrome 配置详解
2019/04/01 PHP
range 标准化之获取
2011/08/28 Javascript
js变量以及其作用域详解
2020/07/18 Javascript
JS实现的省份级联实例代码
2013/06/24 Javascript
jquery ajax修改全局变量示例代码
2013/11/08 Javascript
鼠标滚轮改变图片大小的示例代码
2013/11/20 Javascript
jQuery判断当前点击的是第几个li的代码
2014/09/26 Javascript
js+jquery实现图片裁剪功能
2015/01/02 Javascript
jquery获取多个checkbox的值异步提交给php
2015/07/07 Javascript
JS实现的不规则TAB选项卡效果代码
2015/09/18 Javascript
indexedDB bootstrap angularjs之 MVC DOMO (应用示例)
2016/06/20 Javascript
分分钟玩转Vue.js组件
2016/10/25 Javascript
微信小程序 devtool隐藏的秘密
2017/01/21 Javascript
4个顶级JavaScript高级文本编辑器
2018/10/10 Javascript
在移动端使用vue-router和keep-alive的方法示例
2018/12/02 Javascript
webpack file-loader和url-loader的区别
2019/01/15 Javascript
jQuery控制input只能输入数字和两位小数的方法
2019/05/16 jQuery
JS中call()和apply()的功能及用法实例分析
2019/06/28 Javascript
详解Python中contextlib上下文管理模块的用法
2016/06/28 Python
python实现数据写入excel表格
2018/03/25 Python
浅谈python脚本设置运行参数的方法
2018/12/03 Python
Python中print函数简单使用总结
2019/08/05 Python
python并发编程多进程之守护进程原理解析
2019/08/20 Python
利用Python实现某OA系统的自动定位功能
2020/05/27 Python
Python切片列表字符串如何实现切换
2020/08/06 Python
欧洲当代手工玻璃和瓷器的领先品牌:LSA International
2018/06/03 全球购物
Nisbets爱尔兰:英国最大的厨房和餐饮设备供应商
2019/01/26 全球购物
配件采购员岗位职责
2013/12/03 职场文书
毕业论文评语大全
2014/04/29 职场文书
房地产推广策划方案
2014/05/19 职场文书
平安建设工作方案
2014/06/02 职场文书
2016年离婚协议书范文
2016/03/18 职场文书
MySQL 语句执行顺序举例解析
2022/06/05 MySQL