打造基于jQuery的高性能TreeView

作者: 假正經哥哥  來源: 博客園  發布時間: 2009-10-27 16:33  閱讀: 42079 次  推薦: 8   原文鏈接   [收藏]  

  項目中經常會遇到樹形數據的展現,包括導航,選擇等功能,所以樹控件在大多項目中都是必須的。那一個實用的樹應該具備什么功能呢?

  根據我的項目實踐情況,主要是幾個關鍵點:

  1:支持靜態的樹,即一次性將全部數據加載到客戶端。

  2:異步樹,即一次只加載一級或若干級節點,子節點可以異步加載數據。

  3:Checkbox樹(可能是靜態樹也可能是異步樹),用于選擇(如選擇組織機構,選擇數據字典項)等,最好是能夠支持節點級聯(這個是難點)

  4:能夠承載大數據量,并性能表現優異

  5:能夠在主流瀏覽器中運行良好

  那我要打造的TreeView就是為了實現這個5個主要指標的。

  先來看下效果圖

image

  上圖是中國行政區域的數據樹,總共得節點是3500+。

  那么我們要開工了;

  1:第一個確定的節點Dom結構(即用什么樣的HTML來構建節點)  

  • 比較土的是table套table的(樣式上好控制,但是大數據量,和層次較深的樹,這種結構肯定頂不住的)
  • 還有一種是比較新鮮的UL套LI的方式,這是現下很多書采取的方式如Jquery.treeview就是采用的這種格式,好處比較明顯就是結構簡潔明了,
    而且在不支持Js的瀏覽器上,同樣也能呈現出樹的形狀(這種情況其實咱可以忽略),但是Jquery.treeview的節點在IE下,特別是IE6下無法被內部元素撐開,(IE7,8當達到一定深度時無法撐開),請奇怪的現象(我猜測是因為使用padding來做縮進,margin-left:負值來控制圖標位置有關,但是修改起來難度也較大),在這種情況下書會變形(Jquery.treeview)就有這種問題,只能通過設置節點的width來解決。

image

  JQuery.treeview的節點結構

image

  Jquery.TreeView  IE6 下 展開第三級即出現錯位

image IE8下展開到第5級

  • 還有一些是div套table的方式,CSDN的導航樹就是這種,是種折中的方法(節點也不算太復雜,而且CSS也比較好寫),如下圖所示
    image

 

  而我采用的也是第二種方式,但是縮進采用了填空的方式,即縮進的位置用空白的圖片填充來避免Jquery.treeview的問題

image

  我的樹節點結構

  確定了節點的HTML我們就可以來寫CSS了。有了效果圖,有個節點結構接著就編寫CSS了

  下面是CSS的完整代碼

Code

  上面了樹的基本樣式外,定義了一個有+號帶line的樣式和+號不帶line的樣式

image 這就是那個+號帶line的樣式

  css中所用到的所有圖片

arrows elbow elbow-end elbow-end-minus elbow-end-minus-nl elbow-end-plus elbow-end-plus-nl elbow-line elbow-minus elbow-minus-nl elbow-plus elbow-plus-nl folder folder-open leaf loading

checkbox_2 checkbox_0 checkbox_1

  2:確定數據結構

  這樣的結構有個好處就數據本身是帶層次的,非常利于遍歷,在后面的級聯關聯中會看到

Code

  3: 面子做好了那就開始做里子了,編寫腳本(Javascript)

  我是JQuery得擁護者,所以自然js的框架自然是采用Jquery了

  先上個完整代碼,再逐一分析

Code

  第一步:自然是所有Jquery的控件的第一步都是搭這個架子,兼容JQuery和$避免閉包,避免和其他類庫沖突,接受一個參數(是個對象)

Code

  那第二步:給控件加一些參數默認參數,同時能調用方法$.extend讓最終調用時的參數覆蓋默認的(如果沒有則使用默認)

Code

  第三步:生成默認數據的HTML(根據我們的分析節點的Dom結構,數據的數據結構,生成節點那是非常的簡單),,添加到當前容器中。最后是注冊事件這里有一個非常重要的地方,即懶加載(沒有展開的節點HTML是不生成的),這就要求我們在樹內部要維護一套數據(開銷很小),對于性能的提升那是相當的明顯。另外一個重要的地方,就是使用一次生成所有展開節點的HTML并通過innerHTML屬性來生成Dom,而不是通過append操作,因為直接操作innerHTML比通過dom原生的方法要快上N倍(節點越多,N越大),切記切記!

 

Code
   在節點生成過程中,同時可生產節點的Path(節點路徑),方便檢索

 

Code

  注冊事件,接受參數parent,即從某一父節點開始附加事件(因為做了個hover效果,所以事件是在每個節點上,如果取消該效果,事件可直接附加Tree上通過Event的srcElement來分發可略提升性能

Code

  這里最主要的還是node的click事件,因為他要處理的事情很多,如樹的展開收縮(如果子節點不存在,但是hasChildren為真,同時 complete屬性不為真則需要異步加載子節點,如子節點存在,但是沒有Render那么就要Render),點擊checkbox要出發級聯的事件和 oncheckbox事件,點擊其他則觸發配置條件的nodeonclick事件,這一切都通過前面event的源元素的class來區分點擊的對象

Code

  展開節點,異步請求的部分代碼應該不是很復雜就不細訴了,關鍵來講一下級聯
  級聯有兩個問題要處理,第一個是遍歷子節點,第二個是上溯到祖節點,因為我們的數據結構這兩個操作都顯得非常簡單

Code

  找到節點的同時都會觸發check這個回調函數,來判斷當前節點的狀態,詳細請看下面代碼中的注釋部分應該是比較清晰,描寫了這個過程

Code

  至此我們樹的主體功能已經完全實現了。其他就是公開一些方法等,大家可詳見代碼,示例中公開了兩個一個當前選中的所有節點,另外一個當前的節點。 

  大家可以通過以下網址查看文中的示例,selected拼錯了,大家海涵! windows azure部署還是麻煩懶得修改了3500+節點一次加載,大家可以點擊根節點的全選來看看速度

   http://jscs.cloudapp.net/ControlsSample/BigTreeSample 

  異步加載,按需加載的情況也是非常常用的,使用的是SQL Azure服務器在美國ing,所以可能異步有點慢,本地數據源那是瞬間的

   http://jscs.cloudapp.net/

8
0
 
 
 

文章列表

arrow
arrow
    全站熱搜
    創作者介紹
    創作者 大師兄 的頭像
    大師兄

    IT工程師數位筆記本

    大師兄 發表在 痞客邦 留言(0) 人氣()