天天看點

以正确的姿勢實作一棵JavaScript菜單樹

菜單樹是常見的前端特效, 一般長下面這樣

以正确的姿勢實作一棵JavaScript菜單樹

還有各種形态的變種, 有長這樣的

以正确的姿勢實作一棵JavaScript菜單樹

也有長這樣的

以正确的姿勢實作一棵JavaScript菜單樹

盡管這些菜單的相貌都不盡相同, 在功能實作的本質上卻都是相同的。實作程式的大緻流程如下

讀取伺服器端的菜單資料

将資料轉換成html菜單結構

為菜單結構綁定各種互動事件,如展開、關閉等。

然而, 随着需求的變化, 菜單往往會需要一些基礎之外的功能, 比如說添加菜單項、删除菜單項、修改菜單名、拖拽子菜單至其它父菜單項之下等, 實作這些額外的功能将增加菜單制作的難度。就拿添加菜單項這個功能來講, 添加菜單項事件中代碼的正常實作流程如下

為菜單的html結構添加一個菜單項元素結點并指定節點的名稱

将菜單新節點資料添加至初始化菜單html結構的資料中

将新菜單的資料通過ajax發送至伺服器端持久存儲

删除菜單的流程亦如此

删除菜單中菜單項html節點

删除初始化菜單的資料中對應的資料項

将菜單的辨別通過ajax發送至執行删除操作的伺服器端程式

這種做法不能說有問題, 但是并不完美。 尤其是對于添加菜單項功能, 當菜單項添加完成時還需要為新添加的菜單節點綁定對應的事件 , 這不但使原本隻需要3步的添加操作變成了4步, 還導緻了代碼邏輯的不一緻、程式實作的複雜化,因為綁定事件這一步是重複的,在初始化菜單的時候執行過這項操作。 如何避免此類情況的出現呢? 其實并不難,換種思路即可。

拿添加菜單項這個功能來說, 我們完全可以使用3步操作來替代上面的4步實作操作

直接在菜單的資料源中添加菜單的資料項

重新渲染(初始化)

将資料發送至伺服器端持久儲存

這樣做程式邏輯是不是清晰了很多, 而且渲染這個操作之前就已經實作了, 現在隻需要拿來用就可以了,是以看似3步的操作實質上隻有2步而已, 整個過程得到了極大的簡單。 而且這種做法也适用于删除和修改兩個功能項

删除操作

删除菜單資料中要删除的菜單資料項,并且重新初始化菜單

将資料儲存至伺服器

修改操作

修改菜單資料中的需要修改的資料項,并且重新初始化菜單

如你所見, 所有對菜單的修改操作隻需要針對菜單的資料源就可以了, 對菜單html元素結構的操作都可以省略掉,因為這些功能都已經包含在初始化菜單的過程中了,完全沒有多此一舉的必要再去調用一遍。

這種做法看起來有一個壞處, 就是程式比較耗費性能, 因為每次對菜單的改動都會觸發一次重新初始化菜單的操作。 事實上不必為此擔憂, 首先現代的浏覽器對于界面的渲染優化已至極緻, 其次執行一次菜單初始化操作所占用的使用者計算機資源消耗量幾乎可以忽略不計, 對于使用者體驗更是完全沒有絲毫影響 , 使用者的感觀能力遠沒有靈敏到可以感覺如此微乎其微的變化。反而實作菜單代碼邏輯複雜度的降低為程式員帶來的好處卻非常明顯, 簡化邏輯的好處從開發維護時間成本到程式員的編碼體驗都會有不同程度的展現。

前端和後端不同, 前端程式消耗的資源和運作程式的機器總是一對一的, 是以性能消耗隻要不是太過分, 對于使用者的影響不會很明顯 ; 而後端程式消耗的資源和運作程式的機器往往是多對一的, 隻有拼命的壓榨程式的資源消耗才能降低伺服器的負荷。

是以, 在開發前端程式的時候, 完全可以犧牲部分性能以達到程式邏輯的簡化目的, 這是值得的。

知乎:https://www.zhihu.com/people/aspwebchh

github:https://github.com/aspwebchh

email: [email protected]

繼續閱讀