当前位置: 移动技术网 > IT编程>开发语言>JavaScript > 利用原生JS实现data方法示例代码

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

2019年07月19日  | 移动技术网IT编程  | 我要评论

前言

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

总结

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

如对本文有疑问, 点击进行留言回复!!

相关文章:

验证码:
移动技术网