利用原生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 相关文章推荐
javascript 选择文件夹对话框(web)
Jul 07 Javascript
基于jquery实现的上传图片及图片大小验证、图片预览效果代码
Apr 12 Javascript
Js 冒泡事件阻止实现代码
Jan 27 Javascript
用Jquery.load载入页面实现局部刷新
Jan 22 Javascript
利用JQuery和Servlet实现跨域提交请求示例分享
Feb 12 Javascript
Node调试工具JSHint的安装及配置教程
May 27 Javascript
纯Javascript实现ping功能的方法
Mar 20 Javascript
jquery实现从数组移除指定的值
Jun 24 Javascript
跟我学习javascript的闭包
Nov 16 Javascript
jquery 一键复制到剪切板的实例
Sep 20 jQuery
浅谈Fetch 数据交互方式
Dec 20 Javascript
jQuery实现图片随机切换、抽奖功能(实例代码)
Oct 23 jQuery
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
一个oracle+PHP的查询的例子
2006/10/09 PHP
PHP+MYSQL的文章管理系统(二)
2006/10/09 PHP
编写漂亮的代码 - 将后台程序与前端程序分开
2008/04/23 PHP
PHP访问数据库集群的方法小结
2016/03/14 PHP
PHP pthreads v3下的Volatile简介与使用方法示例
2020/02/21 PHP
Dojo之路:如何利用Dojo实现Drag and Drop效果
2007/04/10 Javascript
js兼容标准的表格变色效果
2008/06/28 Javascript
jquery.ui.progressbar 中文文档
2009/11/26 Javascript
JS继承 笔记
2011/07/13 Javascript
谈一谈JS消息机制和事件机制的理解
2016/04/14 Javascript
JS获取IMG图片高宽的简单实例
2016/05/17 Javascript
全面了解JS中的匿名函数
2016/06/29 Javascript
完美解决IE9浏览器出现的对象未定义问题
2016/09/29 Javascript
原生JS实现Ajax跨域请求flask响应内容
2017/10/24 Javascript
解决微信小程序scroll-view组件无横向滚动的问题
2020/02/04 Javascript
javascript执行上下文、变量对象实例分析
2020/04/25 Javascript
Python操作RabbitMQ服务器实现消息队列的路由功能
2016/06/29 Python
TensorFlow模型保存/载入的两种方法
2018/03/08 Python
python获取网页中所有图片并筛选指定分辨率的方法
2018/03/31 Python
python实现zabbix发送短信脚本
2018/09/17 Python
python图形绘制奥运五环实例讲解
2019/09/14 Python
解决python -m pip install --upgrade pip 升级不成功问题
2020/03/05 Python
python 判断txt每行内容中是否包含子串并重新写入保存的实例
2020/03/12 Python
Python实现ElGamal加密算法的示例代码
2020/06/19 Python
New Balance德国官方网站:购买鞋子和服装
2019/08/31 全球购物
英文版区域经理求职信
2013/10/23 职场文书
函授自我鉴定范文
2014/02/06 职场文书
机关单位动员会主持词
2014/03/20 职场文书
培训班开班仪式主持词
2014/03/28 职场文书
学生会副主席竞聘书
2014/03/31 职场文书
机关单位工作失职检讨书
2014/11/20 职场文书
大四学生个人总结
2015/02/15 职场文书
个人求职信格式范文
2015/03/20 职场文书
2015年体检中心工作总结
2015/05/27 职场文书
导游词之秦始皇兵马俑博物馆
2019/09/29 职场文书
nginx搭建图片服务器的过程详解(root和alias的区别)
2021/03/31 Servers