1. 程式人生 > >項目中jquery插件ztree使用記錄

項目中jquery插件ztree使用記錄

mvvm onclick 阻塞 根據 image [0 情況 ner drag

  最近公司要求做一個關於後臺的管理系統。在這個mvvm模式橫行的年代,雖然這裏用jquery做項目可能有點不符合時代的潮流,但是管他呢,能做出來先在說唄(公司以後要改用angular或者vue來統一前端的制作方式),個人覺得jquery還挺好用的。廢話這裏就不多敘述了。下面就先來一張完成後的圖片展示一下ztree可以完成的功能。

 技術分享

  額····這邊彈出層的陰影是錄制軟件的問題(這邊的前端插件用的是layui,想用的小夥伴可以自行百度layui,順便一提,我這裏用的版本是layui 1.0的,現在layui已經更新到2.0版本了,已經有自適應功能了,挺好用的。你問我為什麽不用bootstrap?其實這個項目中UI小夥伴給我的時候插件用的是bootstrap,但是本人就先入為主了,還是覺得layui輕便好用,看個人喜好吧)。

  忘記了初衷這裏是來介紹ztree的,好了,下面先來介紹下ztree的基本信息。

  使用ztree的時候可以參考官網的教程來一步步跟著做。zTree官網。詳細的api可以參照著官網來看。

  先看ztree的初始化過程:

  

1 zTreeObj = $.fn.zTree.init($obj, setting, nodes);

  這是就是初始加載ztree樹。第一個參數$obj代表的是你需要加載ztree的容器。一般默認是一個div。第二個參數是我們的配置項。下面會詳細介紹,第三個nodes就是我們需要顯示的數據,實際項目中一般都是後臺返回的json.

  上面展示的功能用到了樹的左鍵點擊,郵件點擊,拖拽3個大的功能點。這裏是我項目中寫的setting的內容

 1     var setting = {
 2             callback : {
 3                 onClick : zTreeOnClick,
 4                 onRightClick : zTreeOnRightClick,
 5                 beforeDrag : zTreeBeforeDrag,
 6                 beforeDrop : zTreeBeforeDrop,
 7                 onDrop : zTreeOnDrop,// 如果對象目標不是節點,不會觸發beforeDrop,直接觸發onDrop
8 }, 9 data : { 10 simpleData : { 11 enable : true, 12 idKey : "id", 13 pIdKey : "pId", 14 }, 15 key : { 16 name : "sname" 17 }, 18 keep : { 19 parent : true,//沒有子節點也保持父節點狀態 20 leaf : false 21 } 22 }, 23 edit : { 24 enable : true, 25 showRemoveBtn : false, 26 showRenameBtn : false, 27 drag : { 28 isCopy : false,//拖拽節點不是復制 29 isMove : true,//拖拽節點只是移動 30 prev : true,//可以放到節點前面 31 next : true,//可以放到其他節點後面 32 inner : canInner//能否放到節點裏面看回調函數返回的值 33 } 34 }, 35 view : { 36 selectedMulti : false 37 } 38 };

  這裏常用到的左鍵點擊事件什麽的這裏就不提了,可以參照官網的例子。這裏就記錄下onRightClick事件和onDrop事件。

  首先是onRightClick事件,彈出右鍵菜單欄,然後點擊不同的節點郵件的菜單欄還是不同的。點擊菜單欄上的不同的選項觸發不同的事件。首先我們要讓右鍵樹節點在相應的地方產生菜單。不過不用急,這裏ztree給我們返回的參數中包含了標準的event,右鍵點擊的節點node,還有點擊tree的Id(如果一個頁面中有多棵樹,這個參數就顯得十分重要,如果就一個樹,那麽這個參數就沒什麽多大的作用)。我們可以通過event來確定鼠標在頁面中具體的位置,然後根據node來判斷右鍵菜單的詳細內容和相關的綁定事件。下面是項目中的代碼:

 1     // 右鍵菜單功能
 2     function zTreeOnRightClick(event, treeId, treeNode) {
 3         $(‘#rightMenu‘).remove();// 移出之前的右鍵菜單,如果有;
 4         if (treeNode) {
 5             zTreeObj.selectNode(treeNode);
 6             var isEqu = treeNode.isEqu ? true : false, isEquHtml = "";
 7             if (!isEqu) {
 8                 isEquHtml = "<li id=‘addDep‘>添加部門</li>"
 9                         + "<li id=‘addEqu‘>添加設備</li>";
10             }
11             var editName = isEqu ? "修改設備" : "修改部門";
12             var deleteName = isEqu ? "刪除設備" : "刪除部門";
13             var html = "<ul id=‘rightMenu‘>" + isEquHtml + "<li id=‘edit‘>"
14                     + editName + "</li>" + "<li id=‘delete‘>" + deleteName
15                     + "</li>" + +"</ul>";
16             var menu = $(html).css({
17                 left : event.pageX + 5 + ‘px‘,
18                 top : event.pageY + 5 + ‘px‘
19             });
20             $(‘body‘).append(menu);
21             menuClick();// 給添加的元素綁定事件
22         }
23     }

  我這邊的實際情況是看樹上的節點中是否有isEqu屬性。如果含有這個屬性則證明是設備節點,那麽就只有修改設備和刪除設備2個功能。如果沒有,那麽就證明這個是部門或者公司節點,那麽就有添加設備,添加部門,刪除設備和刪除部門的功能。然後通過jquery的css函數來確定菜單彈出的具體位置。其他的css可以提前在頁面中寫好,比如說hover事件和菜單的樣式。在代碼中只要控制菜單的left和top屬性就行了。這裏值得一提的是,我們給菜單綁定的事件menuClick函數每次都需要在菜單添加的時候運行而不是在$(function(){})中,因為這裏的菜單本身是不存在body中的,是右鍵點擊的時候動態生成的,然後點擊以後又移除了,所以每次生成的時候都需要給這個菜單綁定相關的點擊事件。詳細的點擊事件這裏就不多展開敘述了。

  接下來是拖拽事件。值得一提的是這個beforeDrag和beforeDrop這兩個幾戶一模一樣的回調函數,當時沒註意被搞懵逼了。beforeDrag是拖拽前調用的,beforeDrop是拖拽結束前調用的回調。其原理就是鼠標的mousedown和mouseup還有一個dragflag(拖拽的標誌)。我這裏總公司這個節點是不能移動的,所以在beforeDrap回調裏面判斷一下節點的id,如果是0就代表是總公司,在beforeDrag中返回false就不會再調用onDrag函數了,節點就不能被拖拽。下面是項目中的代碼供參考

    function zTreeBeforeDrag(treeId, treeNodes) {
        if (treeNodes[0].id == 0) {
            layer.msg(‘總公司目錄無法移動!‘, {
                time : 1000
            });
            return false;
        } else {
            return true;
        }
    }

  這裏onDrop回調調用後會自動把移動的節點move到你想要移動的地方。但是我這裏需要加一個是否移動的提示框,所以如果還是用onDrop的話,會直接移動。因為我這裏的彈窗是異步的,js還是會自己執行下去調用onDrop而不管beforeDrop中返回的,除非調用的是系統的comfirm函數,這個會阻塞js進程,但是樣式不好調我就放棄了,我這裏是直接在onDrop中return掉,不讓他移動節點,而是在beforeDrop中自己判斷節點是否可以移動,然後調用ztree的moveNode方法自己移動節點。下面是相關代碼

 1     // 拖拽子節點判斷
 2     function canInner(treeId, treeNodes, targetNode) {
 3         return (targetNode && !targetNode.isEqu);
 4     }
 5     // 拖拽前的判斷
 6     function zTreeBeforeDrop(treeId, treeNodes, targetNode, moveType) {
 7         var msg = ‘是否將 [‘ + treeNodes[0].sname + ‘] 移動到 [‘ + targetNode.sname;
 8         switch (moveType) {
 9         case ‘inner‘:
10             msg += ‘ ]之內?‘;
11             break;
12         case ‘prev‘:
13             msg += ‘ ]之前?‘;
14             break;
15         case ‘next‘:
16             msg += ‘ ]之後?‘;
17         default:
18             break;
19         }
20         layer.confirm(msg, function(index) {
21             zTreeObj.moveNode(targetNode, treeNodes[0], moveType);
22             layer.close(index);
23         });
24         return false;
25     }
26     // 拖拽結束
27     function zTreeOnDrop(event, treeId, treeNodes, targetNode, moveType)     {
28         if (!targetNode) {
29             layer.msg(‘目標對象無效!‘, {
30                 time : 1000
31             });
32             return;
33         }
34     }

  上面代碼僅僅用onDrop函數來提示用戶移動到的節點是無效的這個功能而已,其他功能都是在beforeDrop中實現的。到這裏忘記介紹了nodes這個屬性。我們一般會在setting.data中啟用simpleData,這樣的話我們可以直接設置id和pid2個參數來確定上下級的關系,而不需要嵌套用children這個屬性來確定上下級的關系,這樣的話後臺返回的數據就直接從數據庫中取出返回一個List的類型就行而不需要轉化成復雜的嵌套模式,這個還是挺好用的。下面是我用到的展示的nodes:

 1     var zNodes = [ {
 2         sname : ‘總公司‘,
 3         id : 0,
 4         pId : -1,
 5         open : true,
 6         isParent : true
 7     }, {
 8         sname : ‘技術中心‘,
 9         id : 1,
10         pId : 0,
11         open : true,
12         isParent : true
13     }, {
14         sname : ‘生產中心‘,
15         id : 2,
16         pId : 0,
17         open : true,
18         isParent : true
19     }, {
20         sname : ‘物流中心‘,
21         id : 3,
22         pId : 0,
23         open : true,
24         isParent : true
25     }, {
26         sname : ‘設備1‘,
27         id : 4,
28         pId : 1,
29         isEqu : true,
30 
31     }, {
32         sname : ‘設備2‘,
33         id : 5,
34         pId : 1,
35         isEqu : true,
36 
37     }, {
38         sname : ‘設備3‘,
39         id : 6,
40         pId : 2,
41         isEqu : true,
42     }, {
43         sname : ‘設備4‘,
44         id : 7,
45         pId : 3,
46         isEqu : true,
47     }, ];

  今天這裏的記錄就差不多到這裏了,具體的api還是可以參考官網的。而且官網的教程也很詳細,這裏就不多介紹了,哈哈(真的不是我懶哦)~

項目中jquery插件ztree使用記錄