利用原生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 相关文章推荐
js鼠标点击图片切换效果代码分享
Aug 26 Javascript
完美的js图片轮换效果
Feb 05 Javascript
bootstrap模态框嵌套、tabindex属性、去除阴影的示例代码
Oct 17 Javascript
React Native AsyncStorage本地存储工具类
Oct 24 Javascript
JavaScript实现多重继承的方法分析
Jan 09 Javascript
Vue2.0 http请求以及loading展示实例
Mar 06 Javascript
详解Vue文档中几个易忽视部分的剖析
Mar 24 Javascript
基于Vue实现拖拽功能
Jul 29 Javascript
在vue中使用vue-echarts-v3的实例代码
Sep 13 Javascript
node.js实现带进度条的多文件上传
Mar 27 Javascript
详解Vue 数据更新了但页面没有更新的 7 种情况汇总及延伸总结
May 28 Javascript
Vue 防止短时间内连续点击后多次触发请求的操作
Nov 11 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
基于mysql的论坛(4)
2006/10/09 PHP
php运行时动态创建函数的方法
2015/03/16 PHP
简单了解WordPress开发中update_option()函数的用法
2016/01/11 PHP
PHP fopen函数用法实例讲解
2019/02/15 PHP
jquery tools之tabs 选项卡/页签
2009/07/25 Javascript
玩转jQuery按钮 请告诉我你最喜欢哪些?
2012/01/08 Javascript
Javascript设计模式之观察者模式的多个实现版本实例
2015/03/03 Javascript
javascript中返回顶部按钮的实现
2015/05/05 Javascript
深入理解jQuery之事件移除
2016/06/02 Javascript
使用jQuery Ajax 请求webservice来实现更简练的Ajax
2016/08/04 Javascript
基于jQuery实现简单人工智能聊天室
2017/02/10 Javascript
Bootstrap模态框案例解析
2017/03/05 Javascript
JavaScript实现职责链模式概述
2018/01/25 Javascript
解决 viewer.js 动态更新图片导致无法预览的问题
2019/05/14 Javascript
[01:19:23]2018DOTA2亚洲邀请赛 4.5 淘汰赛 Mineski vs VG 第二场
2018/04/06 DOTA
采用python实现简单QQ单用户机器人的方法
2014/07/03 Python
KMP算法精解及其Python版的代码示例
2016/06/01 Python
python实现对csv文件的列的内容读取
2018/07/04 Python
浅谈python3.x pool.map()方法的实质
2019/01/16 Python
Pycharm编辑器功能之代码折叠效果的实现代码
2020/10/15 Python
CSS3实现任意图片lowpoly动画效果实例
2017/05/11 HTML / CSS
HTML5+CSS3实例 :canvas 模拟实现电子彩票刮刮乐代码
2016/12/30 HTML / CSS
CSS3 分类菜单效果
2019/05/27 HTML / CSS
Urban Outfitters美国官网:美国生活方式品牌
2016/08/26 全球购物
Cole Haan官方网站:美国时尚潮流品牌
2017/12/06 全球购物
美国韩国化妆品和护肤品购物网站:Beautytap
2018/07/29 全球购物
日本最大的旅游网站:Rakuten Travel(乐天旅游)
2018/08/02 全球购物
欧克利英国官网:Oakley英国
2019/08/24 全球购物
有abstract方法的类一定要用abstract修饰吗
2016/03/14 面试题
学年末自我鉴定
2014/01/21 职场文书
公司授权委托书范文
2014/08/02 职场文书
整改落实自查报告
2014/11/05 职场文书
2014年组织部工作总结
2014/11/14 职场文书
2015年中秋晚会主持词
2015/07/01 职场文书
Nginx进程调度问题详解
2021/09/25 Servers
python 闭包函数详细介绍
2022/04/19 Python