在 DOM 上存放數據是否是一個好的解決方案?

我們經常看到這樣的代碼:

&

data-name 作為 JS-Hook(鉤子)可以很方便的被JS取到。

var name = $(".item").attr("data-name");

在大談 MV 分開的今天,在 DOM 上存放數據:

這是否仍然是一個好方法?

該如何理解?

是否有其無可替代的優勢?


既然標準增加了 data-* 就是表示,在DOM存放數據是合理的 use cases。但是,具體案例中,使用 data-* 是不是合適,不能一概而論。

常見的誤用 data-* 的情況:

1. 在HTML中已有更適合的特定屬性。比如語義細化應該用class,而不是data-*;已經有title屬性,不需要用data-tooltip。

2. data-*是特定於網站/應用的,如果是要作為通用協議的(比如提供給第三方),不應該用data-*,而應該考慮microdata、rdfa或microformats。

3. 庫用 data-* 應該加入 namespace 以避免衝突。這一點許多庫(比如bootstrap)做得不好。

前端MV*框架通常並不需要你手動用data-*,因為DOM和數據的關聯是由框架管理的,但是框架可能內部使用data-*作為實現手段。而你用MV*框架的同時又使用bootstrap,那麼bootstrap中component所需的data-*你還是得寫,因為那些data-*是bootstrap的私有屬性,跟MV*沒有關係。


點贊黨出來冒個泡,好像這個問題被winter和hex兩位大神終結了...

不過,個人觀點是方案沒有絕對的對和錯,只是「醜陋」與否而已。

如果你要跨組件交換數據,並且這個數據想綁定在某個控制項上,不管是使用data-*,還是自定義的屬性,也是一個不錯的實踐方案,只是不一定保險而已。

如果不這麼做的話,你需要單獨維護一個全局對象,或者發送全局消息給你想傳遞數據的組件,這個時候,又存在組件的渲染順序的問題and so on..

當然,風險也有:

1.你可以存什麼類型的數值,取出來做類型轉換么,會不會丟失數值,或者發生數值的錯誤;你期待的dom data,會不會被好心人重新渲染了(改寫,empty,remove,或者新添加子元素,且沒有我們想要的屬性..blah....)

當然,邏輯里加些判斷就解決了。

2.讀寫dom-data不及時的情況,A剛讀取了,B就改寫了,A回寫的時候,數據是髒的

需要寫的時候先跟其他組件確認是不是可以寫,或者只讀,或者只寫

暫時寫到這裡,有空再更這個不太好的實踐,:D

......


很明顯這不是一個很好的方案,原因有多種多樣:

1.首先,存在dom上就是很慢,每次訪問數據都要訪問dom

2.個人認為dom上只適合存一些初始化的東西,就是只讀,不存,往dom存數據的意義何在

是時候引入數據倉庫了,我們可以在js中開闢一個數據中心,不走dom

可以看下data.js yanhaijing/data.js · GitHub


我的觀點:datai-id非必需,但寫data-id基本是一定比寫id好的,他損失了一點點性能,卻讓可維護性得到了提升。但是,這個東西不應當被濫用,它的使用場景在HTML模板中。

我們為什麼要用HTML模板呢,因為可能會在頁面上多次根據數據生成某段DOM結構,也可能會對生成的這個DOM結構進行一些操作,理論上,從模板的根部往下去選擇,肯定是可以用路徑描述所有節點的,但太麻煩,所以有時候你會希望直接搞個id,但如果這段模板上存在id,它被外層實例化了多次,這個id在全局作用域中就重複了。從這個角度,你可以把一段模板類比成一個組件。一些高級語言,組件內部是可以有局部作用域的,兩個同級組件中存在同名屬性,是沒什麼問題的,但你要把它搞到一整HTML裡面就重複了,形成了全局變數一樣的效果。如果這時候用的是data-id,就能避免這個問題。

再問一個問題:

如果html不允許自定義屬性,會影響Web產品的實現嗎?顯然不會,因為我們完全可以不用它,而是藉助DOM引用,把DOM跟數據關聯起來。用一些自定義屬性可以降低理解的難度,有些情況下省事點,但我自己基本是不用的……

另外,這個東西要是用得不好,內存泄漏大大的


有時候不得不用 特別是事件代理 回調里根本沒有點擊dom的任何信息,沒辦法找出他的數據


推薦閱讀:

移動端滑動到底部載入更多,是如何做到的?
React中如何實現雙向數據綁定?
為什麼說 DOM 綁定事件很耗性能?
在DOM里 屬性節點是不是元素節點的子節點?
fibjs 對比 nodejs 有哪些優點和缺點?

TAG:前端開發 | JavaScript | DOM |