利用原生JS实现data方法示例代码

 更新时间:2019年05月28日 10:01:04   作者:拭目以待  
这篇文章主要给大家介绍了关于如何利用原生JS实现data方法的相关资料,文中通过示例代码介绍的非常详细,对大家学习或者使用原生JS具有一定的参考学习价值,需要的朋友们下面来一起学习学习吧

前言

在开发中经常会在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

总结

以上就是这篇文章的全部内容了,希望本文的内容对大家的学习或者工作具有一定的参考学习价值,谢谢大家对脚本之家的支持。

相关文章

  • BootStrap入门教程(一)之可视化布局

    BootStrap入门教程(一)之可视化布局

    这篇文章主要介绍了bootstrap可视化布局入门教程的相关资料,本文介绍的非常详细,具有参考借鉴价值,感兴趣的朋友一起看看吧
    2016-09-09
  • JavaScript判断文件是否存在的实例代码

    JavaScript判断文件是否存在的实例代码

    这篇文章主要给大家介绍了关于JavaScript判断文件是否存在的相关资料,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧
    2021-05-05
  • 如何在CocosCreator中利用常驻节点做图层管理

    如何在CocosCreator中利用常驻节点做图层管理

    这篇文章主要介绍了如何在CocosCreator中利用常驻节点做图层管理,这些技巧非常实用,希望同学们看完,回去可以试一下
    2021-04-04
  • 微信小程序调用支付接口的完整流程记录

    微信小程序调用支付接口的完整流程记录

    我们在做小程序支付相关的开发时,总会遇到这些难题,下面这篇文章主要给大家介绍了关于微信小程序调用支付接口的完整流程,文中通过实例代码介绍的非常详细,需要的朋友可以参考下
    2022-02-02
  • 理解Javascript_13_执行模型详解

    理解Javascript_13_执行模型详解

    在《理解Javascript_12_执行模型浅析》一文中,我们初步的了解了执行上下文与作用域的概念,那么这一篇将深入分析执行上下文的构建过程,了解执行上下文、函数对象、作用域三者之间的关系。
    2010-10-10
  • javascript封装addLoadEvent实现页面同时加载执行多个函数的方法

    javascript封装addLoadEvent实现页面同时加载执行多个函数的方法

    这篇文章主要介绍了javascript封装addLoadEvent实现页面同时加载执行多个函数的方法,实例分析了onload事件执行的原理与同时执行多个函数功能的实现技巧,需要的朋友可以参考下
    2016-07-07
  • Three.js GLTF模型加载实现示例详解

    Three.js GLTF模型加载实现示例详解

    这篇文章主要为大家介绍了Three.js GLTF模型加载实现示例详解,有需要的朋友可以借鉴参考下,希望能够有所帮助,祝大家多多进步,早日升职加薪
    2023-04-04
  • Webpack性能优化 DLL 用法详解

    Webpack性能优化 DLL 用法详解

    本篇文章主要介绍了Webpack DLL 用法详解,小编觉得挺不错的,现在分享给大家,也给大家做个参考。一起跟随小编过来看看吧
    2017-08-08
  • 解决layui轮播图有数据不显示的情况

    解决layui轮播图有数据不显示的情况

    今天小编就为大家分享一篇解决layui轮播图有数据不显示的情况,具有很好的参考价值,希望对大家有所帮助。一起跟随小编过来看看吧
    2019-09-09
  • JavaScript如何获取到导航条中HTTP信息

    JavaScript如何获取到导航条中HTTP信息

    这篇文章主要为大家详细介绍了JavaScript如何获取到导航条中HTTP信息,具有一定的参考价值,感兴趣的小伙伴们可以参考一下
    2017-10-10

最新评论