利用原生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 select选中的一个小问题
Oct 11 Javascript
js替换字符串的所有示例代码
Jul 23 Javascript
一个jquery实现的不错的多行文字图片滚动效果
Sep 28 Javascript
实现无刷新联动例子汇总
May 20 Javascript
jQuery实现的个性化返回底部与返回顶部特效代码
Oct 30 Javascript
iscroll.js的上拉下拉刷新时无法回弹的解决方法
Feb 18 Javascript
Bootstrap教程JS插件弹出框学习笔记分享
May 17 Javascript
微信小程序 向左滑动删除功能的实现
Mar 10 Javascript
SVG动画vivus.js库使用小结(实例代码)
Sep 14 Javascript
React Native基础入门之调试React Native应用的一小步
Jul 02 Javascript
vue+Element-ui实现登录注册表单
Nov 17 Javascript
vue如何在data中引入图片的正确路径
Jun 05 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获得用户使用的代理服务器ip即真实ip
2006/12/31 PHP
php绘制一条直线的方法
2015/01/24 PHP
php将print_r处理后的数据还原为原始数组的解决方法
2016/11/02 PHP
php生成二维码图片方法汇总
2016/12/17 PHP
jquery的颜色选择插件实例代码
2008/10/02 Javascript
再论Javascript下字符串连接的性能
2011/03/05 Javascript
javascript 上下banner替换具体实现
2013/11/14 Javascript
每天一篇javascript学习小结(Function对象)
2015/11/16 Javascript
js文本框输入内容智能提示效果
2015/12/02 Javascript
JS与jQuery遍历Table所有单元格内容的方法
2015/12/07 Javascript
使用jquery/js获取iframe父子级、同级获取元素的方法
2016/08/05 Javascript
很实用的js选项卡切换效果
2016/08/12 Javascript
原生JS实现-星级评分系统的简单实例
2016/08/21 Javascript
javascript九宫格图片随机打乱位置的实现方法
2017/03/15 Javascript
webpack配置sass模块的加载的方法
2017/07/30 Javascript
React应用中使用Bootstrap的方法
2017/08/15 Javascript
微信小程序实现长按删除图片的示例
2018/05/18 Javascript
JS实现可用滑块滑动的缓动图代码
2019/09/01 Javascript
JS回调函数深入理解
2019/10/16 Javascript
原生js实现碰撞检测
2020/03/12 Javascript
Vue 禁用浏览器的前进后退操作
2020/09/04 Javascript
Javascript中window.name属性详解
2020/11/19 Javascript
python基础教程之数字处理(math)模块详解
2014/03/25 Python
在Python 3中实现类型检查器的简单方法
2015/07/03 Python
Python3利用Dlib实现摄像头实时人脸检测和平铺显示示例
2019/02/21 Python
python绘制BA无标度网络示例代码
2019/11/21 Python
Python模拟FTP文件服务器的操作方法
2020/02/18 Python
python如何操作mysql
2020/08/17 Python
兰蔻法国官方网站:Lancôme法国
2020/02/22 全球购物
毕业实习个人鉴定范文
2013/12/10 职场文书
同学聚会老师邀请函
2014/01/28 职场文书
《金孔雀轻轻跳》教学反思
2014/04/20 职场文书
事业单位鉴定材料
2014/05/25 职场文书
企业晚会策划方案
2014/05/29 职场文书
给男朋友的道歉短信
2015/05/12 职场文书
Win10服务全部禁用了怎么启动?Win10服务全部禁用解决方法
2022/09/23 数码科技