利用原生JS實(shí)現(xiàn)data方法示例代碼
前言
在開發(fā)中經(jīng)常會(huì)在DOM上存儲(chǔ)一些自定義數(shù)據(jù),我們可以通過setAttribute方法來實(shí)現(xiàn)。但是當(dāng)數(shù)據(jù)為引用類型時(shí),存儲(chǔ)后的數(shù)據(jù)卻無效。這里將用原生的JS對data方法進(jìn)行實(shí)現(xiàn)。
使用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})// 執(zhí)行后DOM節(jié)點(diǎn)變化為<div baukh="[object Object]"></div>
testData.getAttribute('baukh'); // => "[object Object]"
可以從上面的代碼中看出,存進(jìn)去的是個(gè)Object,取出來的是Object.toString()所產(chǎn)出的字符串。
分析
在JS經(jīng)典類庫-jQuery中存在data方法是通過jQuery.cache的方式進(jìn)行數(shù)據(jù)存儲(chǔ),那么還有沒有其它方法可以實(shí)現(xiàn)?
由于使用場景不同,我想實(shí)現(xiàn)的方式是將數(shù)據(jù)直接存儲(chǔ)到DOM節(jié)點(diǎn)上,以達(dá)到使用時(shí)更方便簡捷的目的。
那如何存儲(chǔ)? 變量testData存儲(chǔ)的是通過document.querySeletor('#test-data')獲取到的Element,而Element是Object的一個(gè)實(shí)例。通過[testData instanceof Object]可以進(jìn)行驗(yàn)證。
那么一切都簡易了,即然是Object類型,那么就可以隨意的增刪自定義屬性。
通過在Element的原型上增加data方法來實(shí)現(xiàn)DOM擴(kuò)展
Element.prototype.data = function(key, value){
var _this = this,
_dataName = 'testData', // 存儲(chǔ)至DOM上的對象標(biāo)記, 這里只是測試用名
_data = {};
// 未指定參數(shù),返回全部
if(typeof key === 'undefined' && typeof value === 'undefined'){
return _this[_dataName];
}
// setter
if(typeof(value) !== 'undefined'){
// 存儲(chǔ)值類型為字符或數(shù)字時(shí), 使用attr執(zhí)行
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存儲(chǔ)
現(xiàn)在還有一個(gè)問題, 通過Element.prototype綁定的方法只支持Element類生效,而對NodeList類并無效果.
可以通過下面這些代碼進(jìn)行效果測試:
var testDataList = document.querySelectorAll('.test-data-list'); // 獲取的為NodeList 而非 Element
testDataList.data('name', 'baukh'); // Uncaught TypeError: testDataList.data is not a function
這肯定不是想要的結(jié)果, 那么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 將返回第一個(gè)
}
};
來測試下NodeList類的data實(shí)現(xiàn):
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}
這樣就功能上就完成了.
當(dāng)然也可以將NodeList與Element進(jìn)行互換, 具體情況具體考慮.
很簡單不是嗎?
順帶說一下,Array類型的數(shù)據(jù),也可以增加自定義屬性。
var ar = [1,2,3];
console.log(ar instanceof Object); //true 能添加自定義屬性的原因就在這里,Array也是Object的實(shí)例。
ar.test1 = {a:1,b:2};
console.log(ar); //[1, 2, 3, test1: Object]
console.log(ar.test1); //Object {a: 1, b: 2}
隨筆一行
這是前端最好的時(shí)代, 這也是前端最壞的時(shí)代。 眾多前端框架滿天飛,隨著 jQuery 在前端行業(yè)的慢慢弱化,總是會(huì)有一種斯人遠(yuǎn)去,何者慰籍的感覺?;ッ惆?,各位。
另推薦個(gè)表格組件gridManager
總結(jié)
以上就是這篇文章的全部內(nèi)容了,希望本文的內(nèi)容對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,謝謝大家對腳本之家的支持。
相關(guān)文章
vue-router路由懶加載的實(shí)現(xiàn)(解決vue項(xiàng)目首次加載慢)
這篇文章主要介紹了vue-router路由懶加載的實(shí)現(xiàn)(解決vue項(xiàng)目首次加載慢),小編覺得挺不錯(cuò)的,現(xiàn)在分享給大家,也給大家做個(gè)參考。一起跟隨小編過來看看吧2018-08-08
layui時(shí)間控件選擇時(shí)間范圍的實(shí)現(xiàn)方法
今天小編就為大家分享一篇layui時(shí)間控件選擇時(shí)間范圍的實(shí)現(xiàn)方法,具有很好的參考價(jià)值,希望對大家有所幫助。一起跟隨小編過來看看吧2019-09-09
JS函數(shù)參數(shù)的傳遞與同名參數(shù)實(shí)例分析
這篇文章主要介紹了JS函數(shù)參數(shù)的傳遞與同名參數(shù),結(jié)合實(shí)例形式分析了JS函數(shù)參數(shù)的傳遞與同名參數(shù)相關(guān)原理、使用技巧與操作注意事項(xiàng),需要的朋友可以參考下2020-03-03
JS數(shù)組reduce你不得不知道的25個(gè)高級(jí)用法
reduce作為ES5新增的常規(guī)數(shù)組方法之一,對比forEach 、filter和map,在實(shí)際使用上好像有些被忽略,下面這篇文章主要給大家介紹了關(guān)于JS數(shù)組reduce你不得不知道的25個(gè)高級(jí)用法,需要的朋友可以參考下2021-06-06
JavaScript實(shí)現(xiàn)文字與圖片拖拽效果的方法
這篇文章主要介紹了JavaScript實(shí)現(xiàn)文字與圖片拖拽效果的方法,涉及javascript操作文字與圖片的技巧,具有一定參考借鑒價(jià)值,需要的朋友可以參考下2015-02-02
JavaScript實(shí)現(xiàn)統(tǒng)計(jì)文本框Textarea字?jǐn)?shù)增強(qiáng)用戶體驗(yàn)
現(xiàn)在流行的Twitter等微博客網(wǎng)站,有一個(gè)很好的用戶體驗(yàn),就是在文本框中輸入文字的時(shí)候,會(huì)自動(dòng)統(tǒng)計(jì)輸入的字符,并顯示用戶還能輸入的字符,在限制了140個(gè)字的微博客中,這樣的小提示可以很好的增強(qiáng)用戶體驗(yàn),本文也嘗試著實(shí)現(xiàn)一下2012-12-12
關(guān)于base64編碼和解碼的js工具函數(shù)
這篇文章主要介紹了關(guān)于base64編碼和解碼的js工具函數(shù),具有很好的參考價(jià)值,希望對大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教2023-02-02
微信小程序?qū)崿F(xiàn)自上而下字幕滾動(dòng)
這篇文章主要為大家詳細(xì)介紹了微信小程序?qū)崿F(xiàn)自上而下字幕滾動(dòng),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2018-07-07

