利用原生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 相关文章推荐
查看源码的工具 学习jQuery源码不错的工具
Dec 26 Javascript
js对象继承之原型链继承实例
Jan 10 Javascript
jquery实现弹出层登录和全屏层注册特效
Aug 28 Javascript
javascript字符串函数汇总
Dec 06 Javascript
Jquery遍历select option和添加移除option的实现方法
Aug 26 Javascript
jquery遍历标签中自定义的属性方法
Sep 17 Javascript
Node.js开启Https的实践详解
Oct 25 Javascript
微信小程序 获取相册照片实例详解
Nov 16 Javascript
基于node.js依赖express解析post请求四种数据格式
Feb 13 Javascript
vue :src 文件路径错误问题的解决方法
May 15 Javascript
小程序新版订阅消息模板消息
Dec 31 Javascript
vue 需求 data中的数据之间的调用操作
Aug 05 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之COOKIE支持详解
2010/09/20 PHP
php文件操作相关类实例
2015/06/18 PHP
PHP结合jQuery插件ajaxFileUpload实现异步上传文件实例
2020/08/17 PHP
PHP类的声明与实例化及构造方法与析构方法详解
2016/01/26 PHP
利用php抓取蜘蛛爬虫痕迹的示例代码
2016/09/30 PHP
php利用gd库为图片添加水印
2016/11/09 PHP
Laravel 手动开关 Eloquent 修改器的操作方法
2019/12/30 PHP
一个很酷的拖动层的js类,兼容IE及Firefox
2009/06/23 Javascript
extjs实现选择多表自定义查询功能 前台部分(ext源码)
2011/12/20 Javascript
Jquery实现列表(隔行换色,全选,鼠标滑过当前行)效果实例
2013/06/09 Javascript
理解javascript中的回调函数(callback)
2014/09/02 Javascript
jQuery 1.9移除了$.browser可以使用$.support来替代
2014/09/03 Javascript
JS组件Bootstrap实现弹出框和提示框效果代码
2015/12/08 Javascript
jQuery拖拽排序插件制作拖拽排序效果(附源码下载)
2016/02/23 Javascript
Bootstrap三种表单布局的使用方法
2016/06/21 Javascript
关于vue-resource报错450的解决方案
2017/07/24 Javascript
浅谈关于.vue文件中style的scoped属性
2017/08/19 Javascript
AJAX在JQuery中的应用详解
2019/01/30 jQuery
详解nodejs 开发企业微信第三方应用入门教程
2019/03/12 NodeJs
[05:05]第三天的dota2
2013/07/29 DOTA
使用 Python 获取 Linux 系统信息的代码
2014/07/13 Python
Python读取mat文件,并转为csv文件的实例
2018/07/04 Python
详解Django-restframework 之频率源码分析
2019/02/27 Python
Python实现查找字符串数组最长公共前缀示例
2019/03/27 Python
pandas的相关系数与协方差实例
2019/12/27 Python
Python绘制数码晶体管日期
2021/02/19 Python
女士鞋子、包包和服装在线,第一款10美元:ShoeDazzle
2019/07/26 全球购物
豪华床上用品、床单和浴室必需品:Peacock Alley
2019/09/04 全球购物
印度尼西亚手表和包包商店:Urban Icon
2019/12/12 全球购物
空指针到底是什么
2012/08/07 面试题
Oracle中delete,truncate和drop的区别
2016/05/05 面试题
销售自我评价
2013/10/22 职场文书
顶岗实习协议书
2015/01/29 职场文书
投标单位介绍信
2015/05/05 职场文书
2015大学迎新晚会策划书
2015/07/16 职场文书
晶体管来复再生式二管收音机
2021/04/22 无线电