JS--插件: 樹Tree 開發與實現

   平常在Web項目開發時,常常會碰到樹形架構數據的顯示,從數據庫中獲取數據,而且顯示成樹形。爲了方便,咱們能夠寫一個javascript的一個跨瀏覽器樹控件,後續能夠重複使用。本節分享一個本身開發的JS tree插件,對有須要的朋友能夠直接下載使用。javascript

   Tree插件 須要實現css

       (1)、自動將數據組織成上下級關係,這樣咱們在前端手工添加數據或者從數據庫中獲取到的數據不須要咱們來組織上下級關係html

       (2)、支持自定 加載目錄樹  支持XML、JSON 格式的數據加載前端

       (3)、實現樹節點的選擇(單選、複選[級聯選擇])功能java

       (4)、支持大數據的一次性加載node

       。。。。。。jquery

   下面開始分享本身寫的一個Tree 插件:  此插件基於Jquery  須要引用web

   

    第一:插件中每一個樹節點Node的參數JSON對象以下所示ajax

            nodeItem: function () {
                return {
                    nodecode: "",             //  節點編碼
                    nodetext: "",               //  節點文本 [節點顯示文本]
                    nodetitle: "",               //  節點標題 [用於鼠標移過期顯示的節點文本]
                    supnodecode: "",       //  上級節點編碼 [定義此節點所屬的上級節點編碼,經過此編碼來組成上下級關係]
                    nodeurl: "",                 //  節點URL 表示當前節點自定的連接URL地址
                    iconexpand: "",           //  節點展開圖標 [目錄樹節點自定展開狀態下顯示的圖標,若是爲空,則採用默認的圖標]
                    iconcollapse: ""          //  節點收縮圖標 [目錄樹節點自定收縮狀態下顯示的圖標,若是爲空,則採用默認的圖標]
                }
            }數據庫

     第二:加載目錄樹的三種方法

             一、loadJson(Json)             JSON 對象目錄樹節點數組(一次性完成)

                                                       JSON 格式 是一個Array 數組  每項爲一個 nodeItem 對象的參數
                                                       [

                                                            {   nodecode: "", nodetext: "", nodetitle: "",supnodecode: "",nodeurl: "",iconexpand: "" ,iconcollapse: "" },
                                                            {},...
                                                       ]


             二、loadXml(xml)                 XML字符串格式的節點數據(一次性完成)

                                                        說明:採用XML字符串格式  注意節點 tagName:nodecode nodetext 等 不容許變動 由於程序內部是直接採用這個名字來獲取的        
                                                       <root>
                                                             <item>   //  每個節點 內包含多個數據值   
                                                                  <nodecode><![CDATA[節點編碼值]]></nodecode>    
                                                                  <nodetext><![CDATA[節點名稱文本 ]]></nodetext>
                                                                  <nodetitle><![CDATA[節點鼠標移入顯示提示文本]]></nodetitle>
                                                                  <supnodecode><![CDATA[節點所屬上級即父節點編碼]]></supnodecode>
                                                                  <nodeurl><![CDATA[節點關聯連接地址]]></nodeurl>
                                                                  <iconexpand><![CDATA[節點展開時顯示圖標路徑]]></iconexpand>  
                                                                  <iconcollapse><![CDATA[節點收縮時顯示圖標路徑]]></iconcollapse>  
                                                            </item>

                                                            ... ...
                                                        </root>


             三、經過插件對象 的方法   addNodeItem(nodeItem)      經過手工一條一條的添加節點項目(須要兩步完成) 所有添加完成後
                                                      經過插件對象 makeTree()    再手工調用此方法,則能夠建立樹

 

      第三:目錄樹內部重組上下級關係的事件方法  經過此方法,能夠解決咱們前端再也不須要按照上下級關係來區分。

  1   _createTree: function () {    // 建立樹HTML對象
  2                     // 初始化變量參數
  3                     this._sdpTree.empty();       // 清空目錄樹內的全部內容
  4                     this._fnObject.focusNodeCode = "";
  5                     this._myNodes = [];
  6                     this._hsNodes = new $.Hashtable();
  7                     this._dtNodes = [];
  8                     var _tmNodes = [], F = this._fnObject, P = this._fnObject.options, _this = this;
  9 
 10                     // 重組目錄節點(依次將全部的節點組成本身的樹) 一次循環完成 提升效率
 11                     function Renew_GroupNodes(currNodes) {
 12                         // 重繪節點上下級關係
 13                         function Renew_Tree(reNode) {
 14                             if (_tmNodes[reNode.nodecode]) {
 15                                 for (var n = 0; n < _tmNodes[reNode.nodecode].length; n++) {
 16                                     reNode._childs[n] = _tmNodes[reNode.nodecode][n];
 17                                     reNode._childs[n]._parent = reNode;
 18                                     reNode._childs[n]._firstFlag = (n == 0) ? true : false;
 19                                     reNode._childs[n]._lastFlag = (n == (_tmNodes[reNode.nodecode].length - 1)) ? true : false;
 20                                     reNode._childs[n]._haveChild = (_tmNodes[_tmNodes[reNode.nodecode][n].nodecode]) ? true : false;
 21                                     reNode._childs[n]._nodeLevel = reNode._nodeLevel + 1;
 22                                     Renew_Tree(_tmNodes[reNode.nodecode][n]);  // 迭代循環
 23                                 }
 24                             }
 25                         };
 26 
 27                         var m = 0;
 28                         _tmNodes[P.rootcode] = [];   // 根節點
 29                         for (m = 0; m < currNodes.length; m++) {
 30                             var _nd = currNodes[m];
 31                             _tmNodes[_nd.supnodecode] = _tmNodes[_nd.supnodecode] || [];
 32                             _tmNodes[_nd.supnodecode].push(_nd);
 33                             _this._hsNodes.add(_nd.nodecode, _nd);
 34                         };
 35                         var _rtNodes = _tmNodes[P.rootcode];
 36 
 37                         for (m = 0; m < _rtNodes.length; m++) {
 38                             _this._dtNodes[m] = _rtNodes[m];
 39                             _this._dtNodes[m]._parent = null;
 40                             _this._dtNodes[m]._firstFlag = (m == 0) ? true : false;  // 設置參數
 41                             _this._dtNodes[m]._lastFlag = (m == (_rtNodes.length - 1)) ? true : false;
 42                             _this._dtNodes[m]._haveChild = (_tmNodes[_rtNodes[m].nodecode]) ? true : false;
 43                             _this._dtNodes[m]._nodeLevel = 1;
 44                             Renew_Tree(_rtNodes[m]);                               // 迭代循環
 45                         };
 46 
 47                         _rtNodes = null;
 48                         _tmNodes = null;
 49                     };
 50 
 51                     // 執行節點重組
 52                     Renew_GroupNodes(F.curNodes);
 53                     F.curNodes = [];  // 清空臨時節點數組變量,便於後續從新加載使用
 54 
 55                     // 定義前綴字符
 56                     var full_Prefix = this._myFnId + "_sdptree_node_full";     // 完整的一個節點DIV(包含:連線、+號圖片、節點圖片、選擇框、節點文本)
 57                     var node_Prefix = this._myFnId + "_sdptree_node_span";     // 節點SPAN
 58                     // var plus_Prefix = this._myFnId + "_sdptree_node_plus";     // + 號圖片
 59                     var nimg_Prefix = this._myFnId + "_sdptree_node_icon";     // 節點圖片
 60                     var chkr_Prefix = this._myFnId + "_sdptree_node_chk";      // 選擇圖片
 61                     var text_Prefix = this._myFnId + "_sdptree_node_text";     // 節點文本
 62                     var clip_Prefix = this._myFnId + "_sdptree_node_clip";     // 子節點DIV
 63 
 64                     // 注意點:前臺傳入的全部自定義的圖標,所有已是指定的完整路徑了,因此這裏就不須要轉換
 65                     var _rootCode = P.rootcode;
 66                     if (P.showroot) {           // 斷定是否顯示根節點
 67                         var tmRhtml = [];
 68                         tmRhtml.push('<div id="' + full_Prefix + '_' + _rootCode + '" stype="full" >');
 69                         tmRhtml.push('<span id="' + node_Prefix + '_' + _rootCode + '" class="node_default" stype="node" >');
 70                         if (P.showicon) {
 71                             tmRhtml.push('<span id="' + nimg_Prefix + '_' + _rootCode + '" stype="icon" ');
 72                             if (P.rooticon) {   // 是否客戶自定義的圖片
 73                                 tmRhtml.push('class="custom_img" style="background-image: url(' + (P.rooticon) + ');"');
 74                             } else {                                // 啓用默認的樣式圖片
 75                                 tmRhtml.push('class="root_img"');
 76                             };
 77                             tmRhtml.push(' ></span>');
 78                         };
 79                         if (P.selecttype == "checkbox") {     // 是否開啓選擇按鈕
 80                             tmRhtml.push('<span id="' + chkr_Prefix + '_' + _rootCode + '" stype="check" class="checkbox"></span>');
 81                         } else if (P.selecttype == "radio") {
 82                             tmRhtml.push('<span id="' + chkr_Prefix + '_' + _rootCode + '" stype="check" class="radiobtn"></span>');
 83                         };
 84                         tmRhtml.push('<span id="' + text_Prefix + '_' + _rootCode + '"  class="root_title" stype="text">' + P.roottext + '</span>');
 85                         tmRhtml.push('</span>');
 86                         tmRhtml.push('</div>');
 87                         this._sdpTree.append($(tmRhtml.join("")));
 88                         tmRhtml = null;
 89                     };
 90                     var $clipDom = null;
 91                     if (P.showroot) $clipDom = $('<div id="' + clip_Prefix + '_' + _rootCode + '" class="clipdiv" stype="clip" style="display: block" ></div>');
 92                     var _recHTML = this._createNodes(this._dtNodes);
 93                     if (_recHTML) {
 94                         if ($clipDom) { $clipDom.append($(_recHTML)); this._sdpTree.append($clipDom); } else { this._sdpTree.append($(_recHTML)); };
 95                     } else {
 96                         if ($clipDom) { this._sdpTree.append($clipDom); };
 97                     };
 98                     _recHTML = null;
 99 
100                     // 綁定事件
101                     this._bindEvent();
102                     if (P.openall) { F.expandAll(); };
103                 },
View Code

    

        第四:以上只是簡單的介紹了一下Tree的主要加載和重組方法。下面咱們將完整的JS插件代碼貼出來,代碼中有詳細的註釋

                  插件功能:複選、單選、展開、摺疊、顯示/隱藏節點連線 、支持插入節點、刪除節點、節點小圖標自定義、設置節點選中、獲取目錄樹選擇節點(支持XML,JSON等)

                                  右擊菜單(暫時不支持,由於須要用到彈出層,這裏就屏蔽刪除了此功能)  支持節點單擊、雙擊、節點選擇改變事件等等

(function ($) {
    $.fn.webTree = function () {
        return {
            sdptype: "tree",           // 樹形目錄
            myObject: null,            // Tree 樹Jquery對象 $("#treeID")
            myContainer: null,         // Tree 包圍樹節點的容器Jquery對象[爲了保證滾動條和位置的協調,特加入一個容器]
            myFnId: "",                // Tree 內部使用ID[目錄樹控件能夠不定義ID,此屬性就是爲無ID的狀況下也能適用]
            sdpTree: null,             // Tree 插件自動生成樹節點的包圍容器,與myContainer 容器非同一個容器,是在myContainer的內部
            focusNodeCode: null,       // Tree 樹當前獲取到焦點的節點編碼
            defaults: {                // Tree 樹默認相關參數
                sdpfixed: false,       // Tree 是否設計器設計的固定目錄樹
                showroot: true,        // Tree 是否顯示根目錄
                showline: true,        // Tree 是否顯示鏈接豎線
                showicon: true,        // Tree 是否顯示節點圖片
                selecttype: "",        // Tree 樹節點選擇類型 "":表示無選擇按鈕; checkbox:表示啓用複選按鈕; radio:表示啓用單選按鈕
                cascade: false,        // Tree 開啓複選按鈕時,是否啓用級聯選擇(自動勾選下級及所屬上級)
                popmenu: false,        // Tree 是否啓用右擊彈出菜單
                openall: false,        // Tree 是否展開全部節點;false: 展開第一級
                rooticon: "",          // Tree 根目錄節點自定義顯示圖標文件完整路徑名稱 [平臺設計的則放在對應的圖片目錄中]
                middefticon: "",       // Tree 中間節點收縮自定顯示圖標文件完整路徑名稱
                midexpdicon: "",       // Tree 中間節點展開自定顯示圖標文件完整路徑名稱
                endnodeicon: "",       // Tree 末級節點顯示自定顯示圖標文件完整路徑名稱
                customload: "",        // Tree 樹自定加載事件(事件名稱字符串或事件方法)[主要目的:爲了讓右擊刷新按鈕能找到從新加載數據的源頭方法]
                nodeclick: "",         // Tree 樹目錄節點單擊事件(事件名稱字符串或事件方法)
                nodedblclick: "",      // Tree 樹目錄節點雙擊事件(事件名稱字符串或事件方法)
                checkedchange: "",     // Tree 樹目錄節點選擇改變事件(事件名稱字符串或事件方法)[只有開啓了選擇,纔有效]
                rootcode: "-1",        // Tree 根節點Code ID(目的是爲支持從中間節點進行加載目錄樹的功能)默認爲-1
                roottext: "樹形目錄",  // Tree 根目錄節點名稱
                rooturl: ""            // Tree 根目錄超鏈接URL地址
            },
            options: {},               // Tree 控件最終參數
            curNodes: [],              // Tree 臨時樹節點數組(添加節點時臨時儲存)

            // @ method: init() 插件實例初始化
            // @ depict: 執行插件實例的初始化
            // @ params: [object] element 控件對象
            // @ pbtype: 外部調用方法
            init: function (element) {        // 樹初始化
                this.myObject = $(element);
                if (this.myObject.length == 0) { return; };
                this.myContainer = this.myObject.children('div[sdptype="treebase"]');
                if (this.myContainer.length == 0) { // 從新建立
                    this.myObject.empty().append('<div sdptype="treebase" class="sdp-tree-base" ></div>');
                    this.myContainer = this.myObject.children('div[sdptype="treebase"]');
                };
                this.myFnId = this.myObject.attr("id") || $.newGuid();               // Tree 內部使用ID 用於建立NODE各個節點
                this.myContainer.empty().append('<div class="sdp-tree-in"></div>');  // 添加一個正式的目錄樹容器
                this.sdpTree = this.myContainer.find("div.sdp-tree-in");             // 獲取sdpTree容器Jquery對象

                // 設置內部參數
                this._methods._fnObject = this;
                this._methods._myObject = this.myObject;
                this._methods._myContainer = this.myContainer;
                this._methods._myFnId = this.myFnId;
                this._methods._sdpTree = this.sdpTree;

                // 加載綁定參數
                this._loadParam();
                this._bindEvent();
            },

            // @ method: setOptions() 自定設置控件Options屬性值
            // @ depict: 自定設置控件Options屬性值
            // @ params: [object] options 樹形配置參數 Json格式
            // @ pbtype: 外部調用方法
            setOptions: function (options) {
                if (!options) { options = {}; };
                this.options = $.extend({}, this.options, options);  // 合併目錄樹相關參數
            },

            // @ method: nodeItem() 建立一個空節點參數對象
            // @ depict: 經過此方法建立一個空節點參數對象,用於前臺初始化增長節點或執行插入節點使用,經過擴展方法來組合參數
            // @ return: [array]節點{  // 節點參數
            // @                       nodecode: "",         // string  節點編碼 
            // @                       nodetext: "",         // string  節點名稱文本 
            // @                       nodetitle: "",        // string  節點鼠標移入顯示提示文本
            // @                       supnodecode: "",      // string  節點所屬上級即父節點編碼
            // @                       nodeurl: "",          // string  節點關聯連接地址
            // @                       iconexpand: "",       // string  節點展開時顯示圖標完整路徑
            // @                       iconcollapse: ""      // string  節點收縮時顯示圖標完整路徑
            // @                     }
            // @ pbtype: 外部調用方法
            nodeItem: function () {
                return {
                    nodecode: "",
                    nodetext: "",
                    nodetitle: "",
                    supnodecode: "",
                    nodeurl: "",
                    iconexpand: "",     // 節點展開時顯示圖標完整路徑
                    iconcollapse: ""    // 節點收縮時顯示圖標完整路徑
                };
            },


            // 建立樹形目錄
            // 由開發人員經過如下3種方式建立樹數據
            // 一、loadJson(Json)             JSON 對象目錄樹節點數組(一次性完成)
            // 二、loadXml(xml)               XML字符串格式的節點數據(一次性完成)
            // 三、addNodeItem(nodeItem)      經過手工一條一條的添加節點項目(須要兩步完成)
            // 三、makeTree()                 再手工調用此方法,則能夠建立樹

            // @ method: addNodeItem() 添加目錄樹節點
            // @ depict: 經過此方法向目錄樹添加節點數據
            // @ params: [array] nodeItem{} 格式參數數組
            // @ pbtype: 外部調用方法
            addNodeItem: function (nodeItem) {
                var _curNodeItem = $.extend({}, new this.nodeItem(), nodeItem);   // 合併參數
                if ($.isNull(_curNodeItem.nodecode)) { return; };
                if ($.isNull(_curNodeItem.supnodecode)) { _curNodeItem.supnodecode = this.options.rootcode; };
                this.curNodes[this.curNodes.length] = {                           // 在臨時樹節點數組中添加待加入的節點信息
                    nodecode: _curNodeItem.nodecode,
                    nodetext: _curNodeItem.nodetext || "",
                    nodetitle: _curNodeItem.nodetitle || "",
                    supnodecode: _curNodeItem.supnodecode,
                    nodeurl: _curNodeItem.nodeurl || "",
                    iconexpand: _curNodeItem.iconexpand || "",
                    iconcollapse: _curNodeItem.iconcollapse || "",
                    _parent: null,            // 所屬的父節點 
                    _firstFlag: false,        // 本級中的首位 標誌
                    _lastFlag: false,         // 本級中的末位 標誌
                    _nodeLevel: 0,            // 當前節點級別 默認0
                    _haveChild: false,        // 是否包含下級
                    _childs: []               // 子節點的數組
                };
                _curNodeItem = null;
            },

            // @ method: loadXml() 加載XML格式的節點數據
            // @ depict: 直接加載解析XML格式的節點數據
            // @ params: [object] xml XML格式的節點字符串或XmlDocument對象
            // @ pbtype: 外部調用方法
            loadXml: function (xml) {
                if ($.isNull(this.options.rootcode)) { this.options.rootcode = "-1"; }; // 設置根節點編碼
                this.curNodes = [];                                                     // 清空變量數據
                if (xml) {
                    var currXmlDoc = null;
                    if (typeof (xml) == "object") {
                        currXmlDoc = xml;
                    } else {                          //   string
                        currXmlDoc = $.loadXmlString(String(xml));
                    };
                    if (currXmlDoc) {               // 再次斷定  開始解析
                        for (var nn = 0; nn < currXmlDoc.documentElement.childNodes.length; nn++) {
                            var _curNode = currXmlDoc.documentElement.childNodes[nn];
                            var _curAddItem = new this.nodeItem();
                            for (var jj = 0; jj < _curNode.childNodes.length; jj++) {
                                var _subItem = _curNode.childNodes[jj];
                                switch (_subItem.tagName.toLowerCase()) {
                                    case "nodecode":
                                        _curAddItem.nodecode = $(_subItem).text();
                                        break;
                                    case "nodetext":
                                        _curAddItem.nodetext = $(_subItem).text();
                                        break;
                                    case "nodetitle":
                                        _curAddItem.nodetitle = $(_subItem).text();
                                        break;
                                    case "supnodecode":
                                        _curAddItem.supnodecode = $(_subItem).text();
                                        break;
                                    case "nodeurl":
                                        _curAddItem.nodeurl = $(_subItem).text();
                                        break;
                                    case "iconexpand":
                                        _curAddItem.iconexpand = $(_subItem).text();
                                        break;
                                    case "iconcollapse":
                                        _curAddItem.iconcollapse = $(_subItem).text();
                                        break;
                                };
                            };

                            this.addNodeItem(_curAddItem);
                        }
                    }
                };

                this.makeTree();

                // 說明:採用XML字符串格式
                // <root>
                //    <item>   // 每個節點 內包含多個數據值   
                //        <nodecode><![CDATA[節點編碼值]]></nodecode>";          注意節點 tagName:nodecode nodetext 等 不容許變動 由於程序內部是直接採用這個名字來獲取的         
                //        <nodetext><![CDATA[節點名稱文本 ]]></nodetext>";  
                //        <nodetitle><![CDATA[節點鼠標移入顯示提示文本]]></nodetitle>";  
                //        <supnodecode><![CDATA[節點所屬上級即父節點編碼]]></supnodecode>";  
                //        <nodeurl><![CDATA[節點關聯連接地址]]></nodeurl>"; 
                //        <iconexpand><![CDATA[節點展開時顯示圖標路徑]]></iconexpand>";  
                //        <iconcollapse><![CDATA[節點收縮時顯示圖標路徑]]></iconcollapse>";  
                //    </item>
                //</root>
            },

            // @ method: loadJson() 加載JSON格式的節點數據
            // @ depict: 直接加載解析JSON格式的節點數據
            // @ params: [array] json JSON數據對象
            // @ pbtype: 外部調用方法
            loadJson: function (json) {
                if (!this.options.rootcode) { this.options.rootcode = "-1"; };            // 設置根節點編碼
                this.curNodes = [];                                                       // 清空變量數據
                if (json) {
                    for (var jj = 0; jj < json.length; jj++) {
                        var jsonItem = json[jj];
                        if (!jsonItem.nodecode) { continue; };   // 節點編碼不容許爲空

                        var addsItem = new this.nodeItem();
                        addsItem.nodecode = jsonItem.nodecode;
                        addsItem.nodetext = jsonItem.nodetext || "";
                        addsItem.nodetitle = jsonItem.nodetitle || "";
                        addsItem.supnodecode = jsonItem.supnodecode || "";
                        addsItem.nodeurl = jsonItem.nodeurl || "";
                        addsItem.iconexpand = jsonItem.iconexpand || "";
                        addsItem.iconcollapse = jsonItem.iconcollapse || "";

                        this.addNodeItem(addsItem);   // 添加節點 
                    };
                };
                this.makeTree();

                // JSON 格式 是一個Array 數組 每項爲一個 nodeItem 對象的參數
                // [{ nodecode: "", nodetext: "", nodetitle: "",supnodecode: "",nodeurl: "",iconexpand: "",iconcollapse: ""},
                //   {},...
                // ]
            },

            // @ method: loadNodeItems() 加載NodeItem Array節點數組數據
            // @ depict: 直接加載NodeItem Array節點數組數據
            // @ params: [array] itemArray NodeItem Array節點數組數據
            // @ pbtype: 外部調用方法
            loadNodeItems: function (itemArray) {
                if (!itemArray) { itemArray = []; };
                for (var jj = 0; jj < itemArray.length; jj++) {
                    var ndItem = itemArray[jj];
                    if (!ndItem.nodecode) { continue; };   // 節點編碼不容許爲空
                    this.addNodeItem(ndItem);              // 添加節點 
                };
                this.makeTree();
            },

            // @ method: makeTree() 建立生成樹
            // @ depict: 建立生成樹對象的全部節點並顯示出來
            // @         此方法執行以前須要先獲取或手工添加完成全部樹節點
            // @         前臺JS 必須經過 addNodeItem(nodeItem) 方法添加節點
            // @ pbtype: 外部內部調用方法
            makeTree: function () {
                this.sdpTree.empty();
                this._methods._createTree();
            },

            // @ method: appendNode() 插入節點
            // @ depict: 經過此方法向目錄樹插入新的節點
            // @ params: [array] nodeItem {} 格式參數數組
            // @ pbtype: 外部調用方法
            appendNode: function (nodeItem) {
                var _this = this, P = this.options;
                var curNewNode = $.extend({}, new this.nodeItem(), nodeItem);          // 合併節點輸入參數
                if ($.isNull(curNewNode.nodecode)) { return; };
                if ($.isNull(curNewNode.supnodecode)) { curNewNode.supnodecode = P.rootcode; };
                if (this._methods._hsNodes[curNewNode.nodecode]) { return; };          // 節點編碼已經存在,不執行添加
                if (P.rootcode != curNewNode.supnodecode && !this._methods._hsNodes[curNewNode.supnodecode]) { return; };  // 父節點不爲根節點時,父節點數據不存在,則不執行
                var newNode = {
                    nodecode: curNewNode.nodecode,
                    nodetext: curNewNode.nodetext || "",
                    nodetitle: curNewNode.nodetitle || "",
                    supnodecode: curNewNode.supnodecode,
                    nodeurl: curNewNode.nodeurl || "",
                    iconexpand: curNewNode.iconexpand || "",
                    iconcollapse: curNewNode.iconcollapse || "",
                    _parent: null,            // 所屬的父節點 
                    _firstFlag: false,        // 本級中的首位 標誌
                    _lastFlag: false,         // 本級中的末位 標誌
                    _nodeLevel: 0,            // 當前節點級別 默認0
                    _haveChild: false,        // 是否包含下級
                    _childs: []               // 子節點的數組
                };
                curNewNode = null;
                if (P.rootcode == newNode.supnodecode) {
                    newNode._parent = null;
                    newNode._nodeLevel = 1;
                    var len = this._methods._dtNodes.length;
                    if (len > 0) {
                        this._methods._dtNodes[len - 1]._lastFlag = false;
                        newNode._lastFlag = true;
                    } else {
                        newNode._firstFlag = true;
                        newNode._lastFlag = true;
                    };
                    this._methods._dtNodes.push(newNode);   // 添加到第一級中
                } else {
                    var curParent = this._methods._hsNodes[newNode.supnodecode];
                    newNode._parent = curParent;
                    newNode._nodeLevel = curParent._nodeLevel + 1;
                    if (curParent._haveChild) {
                        curParent._childs[curParent._childs.length - 1]._lastFlag = false;
                        newNode._lastFlag = true;
                    } else {
                        curParent._haveChild = true;
                        newNode._firstFlag = true;
                        newNode._lastFlag = true;
                    };
                    curParent._childs.push(newNode);  // 添加到父節點的子節點數組中
                };
                this._methods._hsNodes.add(newNode.nodecode, newNode);  // 加入HASH

                // 建立節點
                var curNodes = []; curNodes.push(newNode);
                var $appNode = $(this._methods._createNodes(curNodes));
                if (newNode.nodecode == P.rootcode) {
                    if (P.showroot) { this.sdpTree.find("#" + this.myFnId + "_sdptree_node_clip_" + P.rootcode).append($appNode); } else { this.sdpTree.append($appNode); };
                } else {
                    var $parent_clip = this.sdpTree.find("#" + this.myFnId + "_sdptree_node_clip_" + newNode.supnodecode);
                    if ($parent_clip.length > 0) {
                        $parent_clip.append($appNode);
                    }
                    else {
                        $now_clip = $('<div id="' + this.myFnId + '_sdptree_node_clip_' + newNode.supnodecode + '" class="clipdiv" stype="clip" style="display: block" ></div>');
                        $now_clip.append($appNode);
                        this.sdpTree.find("#" + this.myFnId + "_sdptree_node_full_" + newNode.supnodecode).after($now_clip);
                    };
                };

                // 更新節點樣式
                if (newNode.supnodecode == P.rootcode) {   // 上級爲根節點的時候,直接更新前一個節點    
                    if (this._methods._dtNodes.length > 1) {
                        var _prevCode = this._methods._dtNodes[this._methods._dtNodes.length - 2].nodecode;
                        this._methods._updateNode(_prevCode);
                    };
                } else {                                             // 上級不爲根節點時候,直接更新此上級節點
                    this._methods._updateNode(newNode.supnodecode);
                };

                // 綁定節點Hover事件
                $appNode.find("span[stype='node']").hover(function () {
                    var tmTitle = _this._methods._hsNodes[$(this).attr("id").replace(_this.myFnId + "_sdptree_node_span_", "")].nodetitle;
                    if (!tmTitle) { tmTitle = $.text(this); };
                    $(this).addClass("node_hover").attr("title", tmTitle);
                }, function () {
                    $(this).removeClass("node_hover").attr("title", "");
                });
            },

            // @ method: deleteNode()  刪除樹節點
            // @ depict: 刪除指定節點編碼的樹節點
            // @ params: [string] nodeCode 節點編碼
            // @ pbtype: 外部調用方法
            deleteNode: function (nodeCode) {
                if ($.isNull(nodeCode)) { return; };
                if (nodeCode == this.options.rootcode) {
                    this.clearAll();
                } else {
                    if (!this._methods._hsNodes[nodeCode]) { return; };
                    var removeNode = this._methods._hsNodes[nodeCode];
                    var prevNodeCode = this.getPrevNodeCode(nodeCode);
                    var tm2 = 0;

                    // 首先刪除HASH表中的全部子節點 先不刪除自己節點
                    if (removeNode._haveChild) {
                        for (var tm1 = 0; tm1 < removeNode._childs.length; tm1++) {
                            this._methods._removeHashNodes(removeNode._childs[tm1].nodecode);
                        };
                    };

                    // 移除dtNodes數組中的節點項
                    if (removeNode._parent) {
                        for (tm2 = 0; tm2 < removeNode._parent._childs.length; tm2++) {
                            if (removeNode._parent._childs[tm2].nodecode == nodeCode) {
                                removeNode._parent._childs.splice(tm2--, 1);
                                break;
                            };
                        };
                    } else {   // 根目錄下的第一級
                        for (tm2 = 0; tm2 < this._methods._dtNodes.length; tm2++) {
                            if (this._methods._dtNodes[tm2].nodecode == nodeCode) {
                                this._methods._dtNodes.splice(tm2--, 1);
                                break;
                            };
                        };
                    };

                    // 移除DOM Node對象
                    var rmNodeFullDom = this.sdpTree.find("#" + this.myFnId + "_sdptree_node_full_" + nodeCode);
                    var rmNodeClipDom = this.sdpTree.find("#" + this.myFnId + "_sdptree_node_clip_" + nodeCode);
                    if (rmNodeFullDom.length > 0) { rmNodeFullDom.remove(); };
                    if (rmNodeClipDom.length > 0) { rmNodeClipDom.remove(); };

                    // 更新Node父節點的數據
                    var parentND = removeNode._parent;
                    if (!parentND) {
                        for (tm2 = 0; tm2 < this._methods._dtNodes.length; tm2++) {
                            this._methods._dtNodes[tm2]._firstFlag = (tm2 == 0) ? true : false;
                            this._methods._dtNodes[tm2]._lastFlag = (tm2 == (this._methods._dtNodes.length - 1)) ? true : false;
                        };
                    } else {
                        if (parentND._childs.length > 0) {
                            for (tm2 = 0; tm2 < parentND._childs.length; tm2++) {
                                parentND._childs[tm2]._firstFlag = (tm2 == 0) ? true : false;
                                parentND._childs[tm2]._lastFlag = (tm2 == (parentND._childs.length - 1)) ? true : false;
                            };
                        } else {
                            parentND._haveChild = false;
                        };
                    };

                    this._methods._hsNodes.remove(removeNode.nodecode);  // 從Hash表刪除本身

                    // 更新節點樣式
                    if (parentND) {
                        this._methods._updateNode(parentND.nodecode);    // 更新父級節點顯示樣式
                    } else {
                        this._methods._updateNode(prevNodeCode);         // 更新前一級節點顯示樣式
                    };
                };
            },

            // @ method: clearAll()  清空樹節點
            // @ depict: 清空樹全部節點包括參數
            // @ pbtype: public 外部調用方法
            clearAll: function () {
                this.focusNodeCode = null;
                this.curNodes = [];
                this._methods._myNodes = [];
                this._methods._dtNodes = null;
                this._methods._hsNodes = null;
                this.sdpTree.empty();
            },

            // @ method: getNode() 獲取節點對象DIV
            // @ depict: 根據節點 NodeCode 來獲取 
            // @ params: [string] nodeCode 節點編碼
            // @ return: [object] 返回節點DOM元素對象
            // @ pbtype: 外部調用方法
            getNode: function (nodeCode) {
                var retNode = this.sdpTree.find("#" + this.myFnId + "_sdptree_node_full_" + nodeCode);
                return ((retNode.length > 0) ? retNode[0] : null);
            },

            // @ method: getNodeParams() 獲取節點的全部參數
            // @ depict: 根據節點 NodeCode 來獲取 
            // @ params: [string] nodeCode 節點編碼
            // @ return: [object] 返回節點參數對象
            // @ pbtype: 外部調用方法
            getNodeParams: function (nodeCode) {
                var retNodeItem = null;
                if (nodeCode == null) { return retNodeItem; };
                if (nodeCode == this.options.rootcode) {               // 樹根節點
                    retNodeItem = new this.nodeItem();
                    retNodeItem.nodecode = this.options.rootcode;
                    retNodeItem.nodetext = this.options.roottext;
                    retNodeItem.nodeurl = this.options.rooturl;
                    retNodeItem.iconcollapse = this.options.rooticon;
                } else {                                               // 普通節點
                    retNodeItem = this._methods._hsNodes[nodeCode];    // 從數組中獲取此節點的全部值
                };
                return retNodeItem;
            },

            // @ method: getNodeCode() 獲取節點編碼
            // @ depict: 根據節點對象(經過getNode() 方法獲取的節點對象) 來獲取此對象的節點ID
            // @ params: node  object 節點DOM對象
            // @ return: string  返回節點對象的ID
            // @ pbtype: 外部調用方法
            getNodeCode: function (node) {
                var retNodeCode = null;
                if (node) {
                    var tmID = $(node).attr("id");
                    if (tmID) {
                        retNodeCode = tmID.replace(this.myFnId + "_sdptree_node_full_", "");
                    };
                };
                return retNodeCode;
            },

            // @ method: getPrevNodeCode() 獲取指定節點的前一個節點的節點編碼NodeCode
            // @ depict: 根據指定的節點NodeCode來獲取其前一個節點NodeCode 節點編碼
            // @ params: nodeCode  string 指定的節點編碼
            // @ return: string  返回指定的節點NodeCode的前一個節點編碼NodeCode
            // @ pbtype: 外部調用方法
            getPrevNodeCode: function (nodeCode) {
                var _prevCode = null;
                var _curtNode = this._methods._hsNodes[nodeCode];
                if (_curtNode) {
                    if (_curtNode._firstFlag) { return _prevCode; };
                    if (_curtNode.supnodecode == this.options.rootcode) {
                        for (var tm0 = 0; tm0 < this._methods._dtNodes.length; tm0++) {
                            if (this._methods._dtNodes[tm0].nodecode == nodeCode) {
                                _prevCode = this._methods._dtNodes[tm0 - 1].nodecode;
                                break;
                            };
                        };
                    } else {
                        var _parentND = _curtNode._parent;
                        for (var tm1 = 0; tm1 < _parentND._childs.length; tm1++) {
                            if (_parentND._childs[tm1].nodecode == nodeCode) {
                                _prevCode = _parentND._childs[tm1 - 1].nodecode;
                                break;
                            };
                        };
                    };
                };
                return _prevCode;
            },

            // @ method: getNextNodeCode() 獲取指定節點的下一個節點編碼
            // @ depict: 根據指定的節點編碼來獲取其後一個節點編碼NodeCode
            // @ params: nodeCode  string 指定的節點編碼
            // @ return: object  返回指定的節點的後一個節點編碼字符串
            // @ pbtype: 外部調用方法
            getNextNodeCode: function (nodeCode) {
                var _nextCode = null;
                var _curtNode = this._methods._hsNodes[nodeCode];
                if (_curtNode) {
                    if (_curtNode._lastFlag) { return _nextCode; };
                    if (_curtNode.supnodecode == this.options.rootcode) {
                        for (var tm0 = 0; tm0 < this._methods._dtNodes.length; tm0++) {
                            if (this._methods._dtNodes[tm0].nodecode == nodeCode) {
                                _nextCode = this._methods._dtNodes[tm0 + 1].nodecode;
                                break;
                            };
                        };
                    } else {
                        var _parentND = _curtNode._parent;
                        for (var tm1 = 0; tm1 < _parentND._childs.length; tm1++) {
                            if (_parentND._childs[tm1].nodecode == nodeCode) {
                                _nextCode = _parentND._childs[tm1 + 1].nodecode;
                                break;
                            };
                        };
                    };
                };
                return _nextCode;
            },

            // @ method: getParentNodeCode() 獲取指定節點的父級節點編碼
            // @ depict: 根據節點編碼來獲取其父級節點編碼
            // @ params: nodeCode  string 指定的節點編碼
            // @ return: string  返回指定的節點編碼的父級節點編碼
            // @ pbtype: 外部調用方法
            getParentNodeCode: function (nodeCode) {
                var _parentNodeCode = null;
                if (this._methods._hsNodes[nodeCode]) {
                    _parentNodeCode = this._methods._hsNodes[nodeCode].supnodecode;
                };
                return _parentNodeCode;
            },

            // @ method: getFocusNodeCode() 獲取目錄樹當前獲取到焦點的節點編碼
            // @ depict: 獲取當前目錄中,獲取到焦點的即選中的節點編碼 NodeCode
            // @ return: string  返回節點編碼字符串
            // @ pbtype: 外部調用方法
            getFocusNodeCode: function () {
                return this.focusNodeCode;
            },

            // @ method: getNodeLevel() 獲取節點級別層次
            // @ depict: 根據節點編碼來獲取 此節點的層次級別
            // @ params: nodeCode  string 節點編碼
            // @ return: number 節點層次級別,無效返回-1
            // @ pbtype: 外部調用方法
            getNodeLevel: function (nodeCode) {
                if (nodeCode == this.options.rootcode) {
                    return 0;
                } else {
                    if (this._methods._hsNodes[nodeCode]) {
                        return (this._methods._hsNodes[nodeCode])._nodeLevel;
                    } else {
                        return -1;
                    };
                };
            },

            // @ method: getNodeText() 獲取節點文本值
            // @ depict: 根據節點編碼來獲取節點文本值
            // @ params: nodeCode  string 節點編碼
            // @ return: string 節點文本值
            // @ pbtype: 外部調用方法
            getNodeText: function (nodeCode) {
                var tm_Node = this.getNode(nodeCode);
                if (tm_Node) { return $(tm_Node).text(); };
                return null;
            },

            // @ method: getNodeVal() 獲取節點全部值
            // @ depict:根據節點編碼 獲取節點的全部值
            // @ params: nodeCode  string 節點編碼
            // @ return: Array {} 節點數據數組對象
            // @ pbtype:  外部調用方法
            getNodeVal: function (nodeCode) {
                var curNodeItem = new this.nodeItem();
                if (nodeCode == this.options.rootcode) {
                    curNodeItem.nodecode = this.options.rootcode;
                    curNodeItem.nodetext = this.options.roottext;
                    curNodeItem.nodetitle = "";
                    curNodeItem.supnodecode = "";
                    curNodeItem.nodeurl = this.options.rooturl;
                    curNodeItem.iconexpand = this.options.rooticon;
                    curNodeItem.iconcollapse = this.options.rooticon;
                } else {
                    var tm_Node = this._methods._hsNodes[nodeCode];
                    if (tm_Node) {
                        curNodeItem.nodecode = tm_Node.nodecode;
                        curNodeItem.nodetext = tm_Node.nodecode;
                        curNodeItem.nodetitle = tm_Node.nodecode;
                        curNodeItem.supnodecode = tm_Node.nodecode;
                        curNodeItem.nodeurl = tm_Node.nodeurl;
                        curNodeItem.iconexpand = tm_Node.iconexpand;
                        curNodeItem.iconcollapse = tm_Node.iconcollapse;
                    };
                };
                return curNodeItem;
            },

            // @ method: hideNode() 隱藏指定節點
            // @ depict: 根據節點編碼 執行隱藏指定樹節點對象
            // @ params: nodeCode  string 節點編碼
            // @ pbtype: 外部調用方法
            hideNode: function (nodeCode) {
                if (this.options.rootcode == nodeCode) { return; };
                var tm_MyNode = this.getNode(nodeCode);
                if (!tm_MyNode) { return; };
                var tm_SubNode = this.sdpTree.find("#" + this.myFnId + "_sdptree_node_clip_" + nodeCode);
                $(tm_MyNode).hide();
                if (tm_SubNode.length > 0) { $(tm_SubNode).hide(); };
            },

            // @ method: showNode() 顯示指定節點
            // @ depict: 根據節點編碼 執行顯示指定樹節點對象
            // @ params: nodeCode  string 節點編碼
            // @ pbtype: 外部調用方法
            showNode: function (nodeCode) {
                if (this.options.rootcode == nodeCode) { return; };
                var tm_MyNode = this.getNode(nodeCode);
                if (tm_MyNode) {
                    $(tm_MyNode).show();
                    this.collapseNode(nodeCode);
                };
            },

            // @ method: setShowTreeLine() 設置樹節點連線顯示與否
            // @ depict: 設置顯示、隱藏節點連線 [此功能只有當樹期初設置爲顯示樹節點連線的時候才起做用]
            // @ params: boolValue  boolean  說明:true 表示顯示鏈接線  false 表示不顯示
            // @ pbtype: 外部調用方法
            setShowTreeLine: function (boolValue) {
                if (!this.options.showline) { return; };
                var plusList = this.sdpTree.find("span[stype='plus']");
                var lineList = this.sdpTree.find("span[stype='line']");
                var tm0 = 0;
                if ((boolValue) && boolValue == true) {
                    for (tm0 = 0; tm0 < plusList.length; tm0++) {
                        if ($(plusList[tm0]).prop("open")) {
                            if ($(plusList[tm0]).hasClass("node_expd_0n")) {
                                switch ($(plusList[tm0]).attr("collclass")) {
                                    case "node_plug_1l":
                                        $(plusList[tm0]).removeClass("node_plug_0n");
                                        $(plusList[tm0]).removeClass("node_expd_0n");
                                        $(plusList[tm0]).addClass("node_plug_1l");
                                        $(plusList[tm0]).addClass("node_expd_1l");
                                        break;
                                    case "node_plug_2b":
                                        $(plusList[tm0]).removeClass("node_plug_0n");
                                        $(plusList[tm0]).removeClass("node_expd_0n");
                                        $(plusList[tm0]).addClass("node_plug_2b");
                                        $(plusList[tm0]).addClass("node_expd_2b");
                                        break;
                                    case "node_plug_2t":
                                        $(plusList[tm0]).removeClass("node_plug_0n");
                                        $(plusList[tm0]).removeClass("node_expd_0n");
                                        $(plusList[tm0]).addClass("node_plug_2t");
                                        $(plusList[tm0]).addClass("node_expd_2t");
                                        break;
                                    case "node_plug_3a":
                                        $(plusList[tm0]).removeClass("node_plug_0n");
                                        $(plusList[tm0]).removeClass("node_expd_0n");
                                        $(plusList[tm0]).addClass("node_plug_3a");
                                        $(plusList[tm0]).addClass("node_expd_3a");
                                        break;
                                }
                            }
                        } else {
                            if ($(plusList[tm0]).hasClass("node_plug_0n")) {
                                $(plusList[tm0]).removeClass("node_plug_0n");
                                $(plusList[tm0]).addClass($(plusList[tm0]).attr("collclass"));
                            }
                        }
                    };
                    for (tm0 = 0; tm0 < lineList.length; tm0++) {
                        if (($(lineList[tm0]).hasClass("node_line_10")) && ($(lineList[tm0]).hasClass("nullimg"))) { $(lineList[tm0]).removeClass("nullimg"); };
                        if (($(lineList[tm0]).hasClass("node_line_11")) && ($(lineList[tm0]).hasClass("nullimg"))) { $(lineList[tm0]).removeClass("nullimg"); };
                        if (($(lineList[tm0]).hasClass("node_line_20")) && ($(lineList[tm0]).hasClass("nullimg"))) { $(lineList[tm0]).removeClass("nullimg"); };
                        if (($(lineList[tm0]).hasClass("node_line_21")) && ($(lineList[tm0]).hasClass("nullimg"))) { $(lineList[tm0]).removeClass("nullimg"); };
                        if (($(lineList[tm0]).hasClass("node_line_3n")) && ($(lineList[tm0]).hasClass("nullimg"))) { $(lineList[tm0]).removeClass("nullimg"); };
                    };
                } else {
                    for (tm0 = 0; tm0 < plusList.length; tm0++) {
                        var $plusObj = $(plusList[tm0]);
                        if ($plusObj.prop("open")) {
                            if ($plusObj.hasClass("node_expd_1l")) {
                                $plusObj.removeClass("node_plug_1l").removeClass("node_expd_1l").addClass("node_plug_0n").addClass("node_expd_0n").attr("collclass", "node_plug_1l");
                            } else if ($plusObj.hasClass("node_expd_2b")) {
                                $plusObj.removeClass("node_plug_2b").removeClass("node_expd_2b").addClass("node_plug_0n").addClass("node_expd_0n").attr("collclass", "node_plug_2b");
                            } else if ($plusObj.hasClass("node_expd_2t")) {
                                $plusObj.removeClass("node_plug_2t").removeClass("node_expd_2t").addClass("node_plug_0n").addClass("node_expd_0n").attr("collclass", "node_plug_2t");
                            } else if ($plusObj.hasClass("node_expd_3a")) {
                                $plusObj.removeClass("node_plug_3a").removeClass("node_expd_3a").addClass("node_plug_0n").addClass("node_expd_0n").attr("collclass", "node_plug_3a");
                            };
                        } else {
                            if ($plusObj.hasClass("node_plug_1l")) {
                                $plusObj.removeClass("node_plug_1l").addClass("node_plug_0n").attr("collclass", "node_plug_1l");
                            } else if ($plusObj.hasClass("node_plug_2b")) {
                                $plusObj.removeClass("node_plug_2b").addClass("node_plug_0n").attr("collclass", "node_plug_2b");
                            } else if ($plusObj.hasClass("node_plug_2t")) {
                                $plusObj.removeClass("node_plug_2t").addClass("node_plug_0n").attr("collclass", "node_plug_2t");
                            } else if ($plusObj.hasClass("node_plug_3a")) {
                                $plusObj.removeClass("node_plug_3a").addClass("node_plug_0n").attr("collclass", "node_plug_3a");
                            };
                        };
                    };
                    for (tm0 = 0; tm0 < lineList.length; tm0++) {
                        var $lineObj = $(lineList[tm0]);
                        if (($lineObj.hasClass("node_line_10")) && (!$lineObj.hasClass("nullimg"))) { $lineObj.addClass("nullimg"); };
                        if (($lineObj.hasClass("node_line_11")) && (!$lineObj.hasClass("nullimg"))) { $lineObj.addClass("nullimg"); };
                        if (($lineObj.hasClass("node_line_20")) && (!$lineObj.hasClass("nullimg"))) { $lineObj.addClass("nullimg"); };
                        if (($lineObj.hasClass("node_line_21")) && (!$lineObj.hasClass("nullimg"))) { $lineObj.addClass("nullimg"); };
                        if (($lineObj.hasClass("node_line_3n")) && (!$lineObj.hasClass("nullimg"))) { $lineObj.addClass("nullimg"); };
                    };
                };
            },

            // @ method: setShowNodeIcon() 設置樹節點ICON小圖標顯示與否
            // @ depict:設置樹節點是否顯示ICON小圖標
            // @ params: boolValue  boolean  說明:true 表示顯示  false 表示不顯示
            // @ pbtype: 外部調用方法
            setShowNodeIcon: function (boolValue) {
                var tmDisplay = ((boolValue) && boolValue == true) ? "inline-block" : "none";
                var tmIcons = this.sdpTree.find("span[stype='icon']");
                for (var tm0 = 0; tm0 < tmIcons.length; tm0++) { $(tmIcons[tm0]).css("display", tmDisplay); };
            },

            // @ method: setShowSelectBox() 設置樹節點選擇按鈕顯示與否
            // @ depict:設置樹節點是否顯示選擇按鈕(複選框或單選框)
            // @ params: [string]  checkType  顯示按鈕類型:空、radio、checkbox
            // @ pbtype: 外部調用方法
            setShowSelectBox: function (checkType) {
                if (!checkType) { checkType = ""; };
                if (checkType == "checkbox") {
                    this.options.selecttype = "checkbox";
                } else if (checkType == "radio") {
                    this.options.selecttype = "radio";
                } else {
                    this.options.selecttype = "";
                };

                var tmCheckNodes = null;
                if (this.options.selecttype) {
                    tmCheckNodes = this.sdpTree.find("span[stype='check']");
                    if (tmCheckNodes.length > 0) { tmCheckNodes.remove(); };
                    tmCheckNodes = this.sdpTree.find("span[stype='node']");
                    for (var tm0 = 0; tm0 < tmCheckNodes.length; tm0++) {
                        var tm_TitleNode = $(tmCheckNodes[tm0]).find("span[stype='text']");
                        var tm_NodeID = tm_TitleNode.attr("id").replace(this.myFnId + "_sdptree_node_text_", "");
                        if (this.options.selecttype == "checkbox") {
                            $(tm_TitleNode).before('<span class="checkbox" stype="check" id="' + this.myFnId + '_sdptree_node_chk_' + tm_NodeID + '" ></span>');
                        } else {
                            $(tm_TitleNode).before('<span class="radiobtn" stype="check" id="' + this.myFnId + '_sdptree_node_chk_' + tm_NodeID + '" ></span>');
                        };
                    };

                } else {
                    tmCheckNodes = this.sdpTree.find("span[stype='check']");
                    if (tmCheckNodes.length > 0) { tmCheckNodes.remove(); };
                }
            },

            // @ method: checkedAll() 所有選中
            // @ depict: 當樹開始複選時,實現選中所有樹節點 
            // @ pbtype: 外部調用方法
            checkedAll: function () {
                var _chkIcon = this.sdpTree.find("#" + this.myFnId + "_sdptree_node_chk_" + this.options.rootcode);
                if ((_chkIcon) && _chkIcon.length > 0) {
                    this._methods._checkedNodes(_chkIcon, true, true);
                }
            },

            // @ method: unCheckAll() 取消選擇
            // @ depict: 當樹開始複選時,實現取消所有所有樹節點的選中 
            // @ pbtype: 外部調用方法
            uncheckAll: function () {
                var _chkIcon = this.sdpTree.find("#" + this.myFnId + "_sdptree_node_chk_" + this.options.rootcode);
                if ((_chkIcon) && _chkIcon.length > 0) {
                    this._methods._checkedNodes(_chkIcon, false, true);
                }
            },

            // @ method: setOneNodeChecked() 設置節點選中與否 注意:此方法只設置此單個的節點
            // @ depict: 根據節點編碼來設置節點選擇與否 只設置一個節點,下級不進行設置
            // @ params: [string] nodeCode  節點編碼
            // @ params: [bool]   boolChecked 是否選中 說明:true 表示顯示  false 表示不顯示
            // @ pbtype: 外部調用方法
            setOneNodeChecked: function (nodeCode, boolChecked) {
                var boolVal = (boolChecked) ? true : false;
                var chkImg = this.sdpTree.find("#" + this.myFnId + "_sdptree_node_chk_" + nodeCode);
                if ((chkImg) && chkImg.length > 0) {
                    if (boolVal == chkImg.prop("checked")) { return; };
                    if (this.options.selecttype == "radio") {
                        if (boolVal) {
                            var rdoAllIcon = this.sdpTree.find("span[stype='check']");
                            for (var _tt = 0; _tt < rdoAllIcon.length; _tt++) {
                                var _curRadio = $(rdoAllIcon[_tt]);
                                if (_curRadio.prop("checked")) {
                                    _curRadio.prop("checked", false).removeClass("radiobtn").removeClass("radiobtn_check").addClass("radiobtn");
                                };
                            };
                            chkImg.prop("checked", true).removeClass("radiobtn").removeClass("radiobtn_check").addClass("radiobtn_check");
                        } else {
                            chkImg.prop("checked", false).removeClass("radiobtn").removeClass("radiobtn_check").addClass("radiobtn");
                        }
                    } else if (this.options.selecttype == "checkbox") {
                        chkImg.removeClass("checkbox").removeClass("checkbox_check").addClass(((boolVal) ? "checkbox_check" : "checkbox")).prop("checked", boolVal);
                    };
                };
            },

            // @ method: setNodeChecked() 設置節點選中與否 注意:此方法會自動設置下級(根據級聯選擇的原則)
            // @ depict: 根據節點編碼來設置節點選擇與否 
            // @ params: [string] nodeCode  節點編碼
            // @ params: [bool]   boolValue 是否選中 說明:true 表示顯示  false 表示不顯示
            // @ pbtype: 外部調用方法
            setNodeChecked: function (nodeCode, boolValue) {
                var boolVal = (boolValue) ? true : false;
                var chkImg = this.sdpTree.find("#" + this.myFnId + "_sdptree_node_chk_" + nodeCode);
                if ((chkImg) && chkImg.length > 0) {
                    if (this.options.selecttype == "radio") {
                        if (boolVal == chkImg.prop("checked")) { return; };
                        if (boolVal) {
                            var rdoAllIcon = this.sdpTree.find("span[stype='check']");
                            for (var _tt = 0; _tt < rdoAllIcon.length; _tt++) {
                                var _curRadio = $(rdoAllIcon[_tt]);
                                if (_curRadio.prop("checked")) {
                                    _curRadio.prop("checked", false).removeClass("radiobtn").removeClass("radiobtn_check").addClass("radiobtn");
                                };
                            };
                            chkImg.prop("checked", true).removeClass("radiobtn").removeClass("radiobtn_check").addClass("radiobtn_check");
                        } else {
                            chkImg.prop("checked", false).removeClass("radiobtn").removeClass("radiobtn_check").addClass("radiobtn");
                        }
                    } else if (this.options.selecttype == "checkbox") {
                        this._methods._checkedNodes(chkImg, boolVal);
                    };
                };
            },

            // @ method: setNodeText() 設置節點文本值
            // @ depict:設置樹節點內容文本標題
            // @ params: nodeCode     string  節點編碼
            // @ params: nodeText   string  節點文本標題字符
            // @ pbtype: 外部調用方法
            setNodeText: function (nodeCode, nodeText) {
                var txtNode = this.sdpTree.find("#" + this.myFnId + "_sdptree_node_text_" + nodeCode);
                if (txtNode.length > 0) {
                    if ($.isNull(nodeText)) { nodeText = ""; };
                    txtNode.text(nodeText);
                    if (nodeCode == this.options.rootcode) {
                        this.options.roottext = nodeText;
                    } else {
                        this._methods._hsNodes[nodeCode].nodetext = nodeText;
                    };
                };
            },

            // @ method: getNodeChecked() 獲取節點是否選中
            // @ depict:獲取節點是否選中
            // @ params: [string] nodeCode   節點編碼
            // @ return: [bool]   isChecked  返回是否選中(布爾:true/false)
            // @ pbtype: 外部調用方法
            getNodeChecked: function (nodeCode) {
                var isChecked = false;
                var chkImg = this.sdpTree.find("#" + this.myFnId + "_sdptree_node_chk_" + nodeCode);
                if ((chkImg) && chkImg.length > 0) {
                    isChecked = chkImg.prop("checked");
                } else {
                    var tgNd = this.sdpTree.find("#" + this.myFnId + "_sdptree_node_span_" + tgNodeCode);
                    if ((tgNd) && tgNd.length > 0) {
                        isChecked = tgNd.hasClass("node_select");
                    }
                };
                return isChecked;
            },

            // @ method: getCheckedNodes_Array() 獲取選中節點的數組 to Array()
            // @ depict:獲取樹全部選中的節點 返回 Array 數組 
            // @ return: Array 數組  每項根式 item [
            // @                                     (一、nodecode 節點編碼),  
            // @                                     (二、nodename 節點文本),
            // @                                     (三、nodesupcode 上級編碼)
            // @                                     (四、nodelevel 節點級別)
            // @                                   ]
            // @ pbtype: 外部調用方法
            getCheckedNodes_Array: function () {
                var chkNodeList = this.sdpTree.find("span[stype='check']");
                var retArray = new Array();
                var retCode = "", retText = "", retSupCode = "", retLevel = -1; curIcon = null;
                for (var tm1 = 0; tm1 < chkNodeList.length; tm1++) {
                    curIcon = $(chkNodeList[tm1]);
                    if (!curIcon.prop("checked")) { continue; };
                    retCode = curIcon.attr("id").replace(this.myFnId + "_sdptree_node_chk_", "");
                    if (this.options.rootcode == retCode) { continue; };
                    retText = curIcon.parent().text();
                    retSupCode = this._methods._hsNodes[retCode].supnodecode;
                    retLevel = this._methods._hsNodes[retCode]._nodeLevel;
                    retArray[retArray.length] = [retCode, retText, retSupCode, retLevel];
                };
                return retArray;
            },

            // @ method: getCheckedNodes_String() 獲取選中節點的字符串
            // @ depict:獲取樹全部選中的節點 返回 string 字符串(拼接字符串) 
            // @ return:String 中的每項之間用小寫的分號隔開
            // @         每項順序:nodecode(節點編碼),nodename(節點文本),nodesupcode(上級編碼),nodelevel(節點級別);
            // @ pbtype: 外部調用方法
            getCheckedNodes_String: function () {
                var chkNodeList = this.sdpTree.find("span[stype='check']");
                var retString = [], curIcon = null;
                var retCode = "", retText = "", retSupCode = "", retLevel = "-1";
                for (var tm1 = 0; tm1 < chkNodeList.length; tm1++) {
                    curIcon = $(chkNodeList[tm1]);
                    if (!curIcon.prop("checked")) { continue; };
                    retCode = curIcon.attr("id").replace(this.myFnId + "_sdptree_node_chk_", "");
                    if (this.options.rootcode == retCode) { continue; };
                    retText = curIcon.parent().text();
                    retSupCode = this._methods._hsNodes[retCode].supnodecode;
                    retLevel = this._methods._hsNodes[retCode]._nodeLevel;
                    retString.push(retCode + "," + retText + "," + retSupCode + "," + retLevel + ";");
                };
                return retString.join("");
            },

            // @ method: getCheckedNodes_JsonObj() 獲取選中節點的JSON數組
            // @ depict:獲取樹全部選中的節點   返回 Json 對象數組 
            // @ return: JSON 對象數組
            // @         每項 item{ 
            // @                     nodecode: "節點編碼",
            // @                     nodename: "節點文本", 
            // @                     supnodecode: "上級編碼",
            // @                     nodelevel:節點級別
            // @                   }
            // @ pbtype: 外部調用方法
            getCheckedNodes_JsonObj: function () {
                var chkNodeList = this.sdpTree.find("span[stype='check']");
                var retJson = new Array();
                var retCode = "", retText = "", retSupCode = "", retLevel = 0, curIcon = null;
                for (var tm1 = 0; tm1 < chkNodeList.length; tm1++) {
                    curIcon = $(chkNodeList[tm1]);
                    if (!curIcon.prop("checked")) { continue; };
                    retCode = curIcon.attr("id").replace(this.myFnId + "_sdptree_node_chk_", "");
                    if (this.options.rootcode == retCode) { continue; };
                    retText = curIcon.parent().text();
                    retSupCode = this._methods._hsNodes[retCode].supnodecode;
                    retLevel = this._methods._hsNodes[retCode]._nodeLevel;
                    var newItem = {
                        nodecode: retCode,
                        nodetext: retText,
                        supnodecode: retSupCode,
                        nodelevel: retLevel
                    };
                    retJson.push(newItem);
                };
                return retJson;
            },

            // @ method: getCheckedNodes_XmlStr() 獲取樹全部選中的節點XML字符串
            // @ depict:獲取樹全部選中的節點生成固定格式的XML字符串 
            // @ return: XML字符串
            // @         每項 <row>
            // @                   <nodecode><![CDATA[節點編碼]]></nodecode>
            // @                   <nodetext><![CDATA[節點文本]]></nodetext>
            // @                   <supnodecode><![CDATA[上級編碼]]></supnodecode>
            // @                   <nodelevel><![CDATA[節點級別]]></nodelevel>
            // @               </row>
            // @ pbtype:  外部調用方法
            getCheckedNodes_XmlStr: function () {
                var chkNodeList = this.sdpTree.find("span[stype='check']");
                var retXml = ["<root>"];
                var retCode = "", retText = "", retSupCode = "", retLevel = 0, curIcon = null;
                for (var tm1 = 0; tm1 < chkNodeList.length; tm1++) {
                    curIcon = $(chkNodeList[tm1]);
                    if (!curIcon.prop("checked")) { continue; };
                    retCode = curIcon.attr("id").replace(this.myFnId + "_sdptree_node_chk_", "");
                    if (this.options.rootcode == retCode) { continue; };
                    retText = curIcon.parent().text();
                    retSupCode = this._methods._hsNodes[retCode].supnodecode;
                    retLevel = this._methods._hsNodes[retCode]._nodeLevel;
                    retXml.push("<row><nodecode><![CDATA[" + retCode + "]]></nodecode><nodetext><![CDATA[" + retText + "]]></nodetext><supnodecode><![CDATA[" + retSupCode + "]]></supnodecode><nodelevel><![CDATA[" + retLevel + "]]></nodelevel></row>");
                };
                retXml.push("</root>");
                return retXml.join("");
            },

            // @ method: getCheckedNodes_Hash() 獲取樹全部選中的節點HASH數組
            // @ depict:獲取樹全部選中的節點 返回Hash 數組 
            // @ return: Hash 中的每項:Hash.add(key=nodeID,value=nodeText);
            // @         item[key:nodeID] = value:nodeText
            // @         根據key: hash[key] 獲取返回值:value
            // @ pbtype: 外部調用方法
            getCheckedNodes_Hash: function () {
                var chkNodeList = this.sdpTree.find("span[stype='check']");
                var retHash = $.Hashtable();
                var retCode = "", retText = "", curIcon = null;
                for (var tm1 = 0; tm1 < chkNodeList.length; tm1++) {
                    curIcon = $(chkNodeList[tm1]);
                    if (!curIcon.prop("checked")) { continue; };
                    retCode = curIcon.attr("id").replace(this.myFnId + "_sdptree_node_chk_", "");
                    if (this.options.rootcode == retCode) { continue; };
                    retText = curIcon.parent().text();
                    retHash.add(retCode, retText);
                };
                return retHash;
            },

            // @ method: getAllNodes_Hash() 獲取樹全部節點HASH數組
            // @ depict:獲取樹全部節點HASH數組 返回Hash 數組 
            // @ return: Hash 中的每項:Hash.add(key=nodeID,value=nodeText);
            // @         item[key:nodeID] = value:nodeText
            // @         根據key: hash[key] 獲取返回值:value
            // @ pbtype:  外部調用方法
            getAllNodes_Hash: function () {
                return this._methods._hsNodes;
            },

            // @ method: getAllNodes_Array() 獲取樹全部節點Array數組[分級的]
            // @ depict:獲取樹全部節點 返回 Array 數組  
            // @ pbtype:  外部調用方法
            getAllNodes_Array: function () {
                return this._methods._dtNodes;
            },

            // @ method: expandNode() 展開全部節點
            // @ depict: 展開目錄樹的全部節點
            // @ pbtype: 外部調用方法
            expandAll: function () {
                for (var tm0 = 0; tm0 < this._methods._dtNodes.length; tm0++) {
                    var tm_ExpNode = this._methods._dtNodes[tm0];
                    if (tm_ExpNode._haveChild) {
                        this.expandNode(tm_ExpNode.nodecode);
                        this.expandAllChilds(tm_ExpNode.nodecode);
                    };
                };
            },

            // @ method: expandAllChilds() 展開指定節點的全部子節點
            // @ depict: 展開目錄樹的中執行節點下的全部子節點
            // @ params: nodeCode  string 節點編碼
            // @ pbtype: 外部調用方法
            expandAllChilds: function (nodeCode) {
                var tsNode = this._methods._hsNodes[nodeCode];
                if (tsNode._haveChild) {
                    for (var tm2 = 0; tm2 < tsNode._childs.length; tm2++) {
                        var subNode = tsNode._childs[tm2];
                        if (subNode._haveChild) {
                            this.expandNode(subNode.nodecode);
                            this.expandAllChilds(subNode.nodecode);
                        };
                    };
                };
            },

            // @ method: expandNode() 展開指定的節點
            // @ depict: 根據節點編碼 執行展開此節點
            // @ params: nodeCode  string 節點編碼
            // @ pbtype: 外部調用方法
            expandNode: function (nodeCode) {
                var $plusImg = this.sdpTree.find("#" + this.myFnId + "_sdptree_node_plus_" + nodeCode);
                var $clipDiv = this.sdpTree.find("#" + this.myFnId + "_sdptree_node_clip_" + nodeCode);
                var $nodeIcn = this.sdpTree.find("#" + this.myFnId + "_sdptree_node_icon_" + nodeCode);
                if ($plusImg.length > 0) {
                    if ($plusImg.hasClass("node_plug_0n")) {
                        if (!$plusImg.hasClass("node_expd_0n")) { $plusImg.addClass("node_expd_0n").prop("open", true); };
                    } else if ($plusImg.hasClass("node_plug_1l")) {
                        if (!$plusImg.hasClass("node_expd_1l")) { $plusImg.addClass("node_expd_1l").prop("open", true); };
                    } else if ($plusImg.hasClass("node_plug_2b")) {
                        if (!$plusImg.hasClass("node_expd_2b")) { $plusImg.addClass("node_expd_2b").prop("open", true); };
                    } else if ($plusImg.hasClass("node_plug_2t")) {
                        if (!$plusImg.hasClass("node_expd_2t")) { $plusImg.addClass("node_expd_2t").prop("open", true); };
                    } else if ($plusImg.hasClass("node_plug_3a")) {
                        if (!$plusImg.hasClass("node_expd_3a")) { $plusImg.addClass("node_expd_3a").prop("open", true); };
                    };
                };

                if ($clipDiv.length > 0) { $clipDiv.css("display", "block"); };
                if ($nodeIcn.length > 0) {
                    if ($nodeIcn.hasClass("custom_img")) {
                        var icnBgImg = ($nodeIcn.attr("expdimg")) ? $nodeIcn.attr("expdimg") : $nodeIcn.attr("collimg");
                        $nodeIcn.css("background-image", "url(" + icnBgImg + ")");
                    } else {
                        if (($nodeIcn.hasClass("folder_collapse")) && (!$nodeIcn.hasClass("folder_expand"))) { $nodeIcn.addClass("folder_expand"); };
                    }
                };
            },

            // @ method: collapseAll() 收縮全部節點
            // @ depict: 收縮目錄樹的全部節點
            // @ pbtype: 外部調用方法
            collapseAll: function () {
                for (var tm0 = 0; tm0 < this._methods._dtNodes.length; tm0++) {
                    var tm_CollNode = this._methods._dtNodes[tm0];
                    if (tm_CollNode._haveChild) {
                        this.collapseNode(tm_CollNode.nodecode);
                        this.collapseAllChilds(tm_CollNode.nodecode);
                    };
                };
            },

            // @ method: collapseAllChilds() 收縮指定節點的全部子節點
            // @ depict: 收縮目錄樹的中執行節點下的全部子節點
            // @ params: nodeCode  string 節點編碼
            // @ pbtype: 外部調用方法
            collapseAllChilds: function (nodeCode) {
                var tsNode = this._methods._hsNodes[nodeCode];
                if (tsNode._haveChild) {
                    for (var tm2 = 0; tm2 < tsNode._childs.length; tm2++) {
                        var subNode = tsNode._childs[tm2];
                        if (subNode._haveChild) {
                            this.collapseNode(subNode.nodecode);
                            this.collapseAllChilds(subNode.nodecode);
                        };
                    };
                };
            },

            // @ method: collapseNode() 收縮指定的節點
            // @ depict: 根據節點編碼收縮此節點 
            // @ params: nodeCode  string 節點編碼
            // @ pbtype: 外部調用方法
            collapseNode: function (nodeCode) {
                var $plusImg = this.sdpTree.find("#" + this.myFnId + "_sdptree_node_plus_" + nodeCode);
                var $clipDiv = this.sdpTree.find("#" + this.myFnId + "_sdptree_node_clip_" + nodeCode);
                var $nodeIcn = this.sdpTree.find("#" + this.myFnId + "_sdptree_node_icon_" + nodeCode);
                if ($plusImg.length > 0) {
                    if ($plusImg.hasClass("node_plug_0n")) {
                        if ($plusImg.hasClass("node_expd_0n")) { $plusImg.removeClass("node_expd_0n").prop("open", false); };
                    } else if ($plusImg.hasClass("node_plug_1l")) {
                        if ($plusImg.hasClass("node_expd_1l")) { $plusImg.removeClass("node_expd_1l").prop("open", false); };
                    } else if ($plusImg.hasClass("node_plug_2b")) {
                        if ($plusImg.hasClass("node_expd_2b")) { $plusImg.removeClass("node_expd_2b").prop("open", false); };
                    } else if ($plusImg.hasClass("node_plug_2t")) {
                        if ($plusImg.hasClass("node_expd_2t")) { $plusImg.removeClass("node_expd_2t").prop("open", false); };
                    } else if ($plusImg.hasClass("node_plug_3a")) {
                        if ($plusImg.hasClass("node_expd_3a")) { $plusImg.removeClass("node_expd_3a").prop("open", false); };
                    };
                };
                if ($clipDiv.length > 0) { $clipDiv.css("display", "none"); };
                if ($nodeIcn.length > 0) {
                    if ($nodeIcn.hasClass("custom_img")) {
                        var icnBgImg = ($nodeIcn.attr("collimg")) ? $nodeIcn.attr("collimg") : $nodeIcn.attr("expdimg");
                        $nodeIcn.css("background-image", "url(" + icnBgImg + ")");
                    } else {
                        if (($nodeIcn.hasClass("folder_collapse")) && ($nodeIcn.hasClass("folder_expand"))) {
                            $nodeIcn.removeClass("folder_expand");
                        }
                    }
                };
            },

            // @ method: expandLevel() 展開目錄樹中某層次全部節點 
            // @ depict: 根據節點層次級別
            // @ params: levelNum  [number]  節點層次級別[注意級別是從1開始,根目錄屬於0級]
            // @ pbtype: 外部調用方法
            expandLevel: function (levelNum) {
                levelNum = parseInt(levelNum, 10);
                if (isNaN(levelNum)) { return; };
                var _treeNodesHash = this._methods._hsNodes;
                for (var ll = 1; ll <= levelNum; ll++) {
                    for (var ndCode in _treeNodesHash) {
                        if (_treeNodesHash.hasOwnProperty(ndCode)) {
                            var ndItem = _treeNodesHash[ndCode];
                            if (ndItem._nodeLevel == ll) {
                                this.expandNode(ndItem.nodecode);
                            }
                        }
                    };
                };
            },

            // @ method: collapseLevel() 收縮目錄樹中某層次全部節點 
            // @ depict: 根據節點層次級別
            // @ params: levelNum  [number]  節點層次級別[注意級別是從1開始,根目錄屬於0級]
            // @ pbtype: 外部調用方法
            collapseLevel: function (levelNum) {
                levelNum = parseInt(levelNum, 10);
                if (isNaN(levelNum)) { return; };

                var _treeNodesHash = this._methods._hsNodes;
                for (var ndCode in _treeNodesHash) {
                    if (_treeNodesHash.hasOwnProperty(ndCode)) {
                        var ndItem = _treeNodesHash[ndCode];
                        if (ndItem._nodeLevel == levelNum) {
                            this.collapseNode(ndItem.nodecode); // 收縮指定的節點
                        }
                    }
                };
            },

            // @ method: getObject() 獲取控件JQUERY 對象
            // @ depict: 獲取插件所對應的DOM 控件 JQUERY 對象
            // @ return: [object]  返回控件JQUERY 對象 空爲null
            // @ pbtype: 外部調用方法
            getObject: function () {
                return this.myObject;
            },

            // @ method: getID() 獲取控件ID
            // @ depict: 獲取此插件對應的控件ID屬性值
            // @ return: [string] 控件ID
            // @ pbtype: 外部調用方法
            getID: function () {
                var _thisID = null;
                if (this.myObject != null) { _thisID = this.myObject.attr("id"); };
                if ($.isNull(_thisID) == true) { _thisID = null; };
                return _thisID;
            },

            // @ method: getSdpID() 獲取控件內嵌 ID
            // @ depict: 獲取此插件對應的控件SDP ID屬性值
            // @ pbtype: 外部調用方法
            getSdpID: function () {
                var _thisSdpID = null;
                if (this.myObject != null) { _thisSdpID = this.myObject.attr("sdpid"); };
                if ($.isNull(_thisSdpID) == true) { _thisSdpID = null; };
                return _thisSdpID;
            },

            // @ method: onLocked() 鎖定控件
            // @ depict: 執行控件的鎖定
            // @ pbtype: 外部調用方法
            onLocked: function () {
                if (this.myObject == null) { return; };
                if (this.getLocked() == false) {
                    this.myObject.attr("sdplocked", "yes");
                }
            },

            // @ method: onUnLock() 解鎖控件
            // @ depict: 執行控件的鎖定
            // @ pbtype: 外部調用方法
            onUnLock: function () {
                if (this.myObject == null) { return; };
                if (this.getLocked() == true) {
                    this.myObject.attr("sdplocked", "no");
                }
            },

            // @ method: getLocked() 獲取控件是否鎖定
            // @ depict: 獲取控件的鎖定狀態
            // @ return: [bool] 控件鎖定狀態 true false
            // @ pbtype: 外部調用方法
            getLocked: function () {
                if (this.myObject) {
                    return (this.myObject.attr("sdplocked") == "yes");
                } else {
                    return false;
                }
            },

            // @ method: getVisible() 獲取控件是否可見
            // @ depict: 獲取控件的可見狀態(顯示/隱藏)
            // @ return: [bool] 控件鎖定狀態 true: 表示顯示(可見); false:表示隱藏(不可見)
            // @ pbtype: 外部調用方法
            getVisible: function () {
                if (this.myObject != null) {
                    return this.myObject.is(":hidden");
                } else {
                    return true;
                }
            },

            // @ method: onRefresh() 樹刷新
            // @ depict: 目錄樹刷新[當前樹是經過自動加載的時,即從SQL中獲取有效]
            // @ pbtype: 外部調用方法
            onRefresh: function () {
                var P = this.options;
                this.focusNodeCode = "";
            },

            // @ method: _loadParam() 加載控件Option參數
            // @ depict: 加載控件在設計器中Option參數
            // @ pbtype: 內部調用方法
            _loadParam: function () {
                this.options = $.extend({}, this.defaults);  // 合併參數
            },

            // @ method: _bindEvent() 事件綁定
            // @ depict: 執行控件 樣式、事件等綁定
            // @ pbtype: 內部調用方法
            _bindEvent: function () {
                if (!this.myContainer) { return; };
                var _this = this;
                this.myContainer.click(function (event) {
                    _this._onClickHandle(event);
                }).dblclick(function (event) {
                    _this._onDblClickHandle(event);
                }).contextmenu(function (event) {
                    return false;
                });
            },

            // @ method: _onClickHandle() 節點單擊事件處理
            // @ depict: 對目錄樹節點的單擊事件處理
            // @ params: [object] event 當前目標對象(DOM)
            // @ pbtype: 內部調用方法
            _onClickHandle: function (event) {
                var e = window.event || event;
                e = e.srcElement || e.target;
                if (e.tagName.toLowerCase() != "span") { return; };
                var tgObj = $(e);
                var tgNodeCode = null, tgNd = null;
                switch (tgObj.attr("stype")) {
                    case "text":
                        tgNodeCode = tgObj.attr("id").replace(this.myFnId + "_sdptree_node_text_", "");
                        tgNd = this.sdpTree.find("#" + this.myFnId + "_sdptree_node_span_" + tgNodeCode);
                        if (!tgNd.hasClass("node_select")) {
                            tgNd.addClass("node_select");
                            var forFocus = this.sdpTree.find("#" + this.myFnId + "_sdptree_node_span_" + this.focusNodeCode);
                            if (forFocus.length > 0) { forFocus.removeClass("node_select"); };
                            this.focusNodeCode = tgNodeCode;
                        };
                        this._onNodeClick(tgNd);
                        break;
                    case "plus":
                        tgNodeCode = tgObj.attr("id").replace(this.myFnId + "_sdptree_node_plus_", "");
                        if (typeof (tgObj.prop("open")) == "undefined") {
                            if (tgObj.hasClass("node_plug_0n")) {
                                if (tgObj.hasClass("node_expd_0n")) { tgObj.prop("open", true); } else { tgObj.prop("open", false); };
                            } else if (tgObj.hasClass("node_plug_1l")) {
                                if (tgObj.hasClass("node_expd_1l")) { tgObj.prop("open", true); } else { tgObj.prop("open", false); };
                            } else if (tgObj.hasClass("node_plug_2b")) {
                                if (tgObj.hasClass("node_expd_2b")) { tgObj.prop("open", true); } else { tgObj.prop("open", false); };
                            } else if (tgObj.hasClass("node_plug_2t")) {
                                if (tgObj.hasClass("node_expd_2t")) { tgObj.prop("open", true); } else { tgObj.prop("open", false); };
                            } else if (tgObj.hasClass("node_plug_3a")) {
                                if (tgObj.hasClass("node_expd_3a")) { tgObj.prop("open", true); } else { tgObj.prop("open", false); };
                            };
                        };
                        if (tgObj.prop("open")) { this.collapseNode(tgNodeCode); } else { this.expandNode(tgNodeCode); };
                        break;
                    case "check":
                        if (this.getLocked() == true) { return; };
                        tgNodeCode = tgObj.attr("id").replace(this.myFnId + "_sdptree_node_chk_", "");
                        tgNd = this.sdpTree.find("#" + this.myFnId + "_sdptree_node_span_" + tgNodeCode);
                        var _oldCheckState = tgObj.prop("checked") || false;
                        this.setNodeChecked(tgNodeCode, !tgObj.prop("checked"));
                        var _newCheckState = tgObj.prop("checked") || false;
                        if (_oldCheckState != _newCheckState) { this._onNodeCheckedChange(tgNd); };
                        break;
                };
            },

            // @ method: _onDblClickHandle() 節點雙擊事件處理
            // @ depict: 對目錄樹節點的雙擊事件處理
            // @ params: [object] event 當前目標對象(DOM)
            // @ pbtype: 內部調用方法
            _onDblClickHandle: function (event) { // 節點雙擊事件
                var e = event || window.event;
                e = e.srcElement || e.target;
                if (e.tagName.toLowerCase() != "span") { return; };
                var dblOBJ = $(e);
                if (dblOBJ.attr("stype") == "text") {
                    var dblNodeCode = dblOBJ.attr("id").replace(this.myFnId + "_sdptree_node_text_", "");
                    var plusOBJ = this.sdpTree.find("#" + this.myFnId + "_sdptree_node_plus_" + dblNodeCode);
                    var tgNd = this.sdpTree.find("#" + this.myFnId + "_sdptree_node_span_" + dblNodeCode);
                    if (plusOBJ.length > 0) {
                        if (typeof (plusOBJ.prop("open")) == "undefined") {
                            if (plusOBJ.hasClass("node_plug_0n")) {
                                if (plusOBJ.hasClass("node_expd_0n")) { plusOBJ.prop("open", true); } else { plusOBJ.prop("open", false); };
                            } else if (plusOBJ.hasClass("node_plug_1l")) {
                                if (plusOBJ.hasClass("node_expd_1l")) { plusOBJ.prop("open", true); } else { plusOBJ.prop("open", false); };
                            } else if (plusOBJ.hasClass("node_plug_2b")) {
                                if (plusOBJ.hasClass("node_expd_2b")) { plusOBJ.prop("open", true); } else { plusOBJ.prop("open", false); };
                            } else if (plusOBJ.hasClass("node_plug_2t")) {
                                if (plusOBJ.hasClass("node_expd_2t")) { plusOBJ.prop("open", true); } else { plusOBJ.prop("open", false); };
                            } else if (plusOBJ.hasClass("node_plug_3a")) {
                                if (plusOBJ.hasClass("node_expd_3a")) { plusOBJ.prop("open", true); } else { plusOBJ.prop("open", false); };
                            };
                        };
                        if (plusOBJ.prop("open")) {
                            this.collapseNode(dblNodeCode);
                        }
                        else { this.expandNode(dblNodeCode); };
                    };
                    this._onNodeDblClick(tgNd);
                };
            },

            // @ method: _onNodeClick() 執行節點自定單擊事件
            // @ depict: 執行節點自定單擊事件
            // @ params: [object] node 樹節點DOM對象 
            // @ pbtype: 內部調用方法
            _onNodeClick: function (node) {
                if (!node) { return; };
                var nodeClickEvent = this.options.nodeclick;
                if (typeof (nodeClickEvent) != 'function') { nodeClickEvent = $.strToFunction(nodeClickEvent); };
                if (typeof (nodeClickEvent) == 'function') {
                    try {
                        var ndCode = $(node).attr("id").replace(this.myFnId + "_sdptree_node_span_", "");
                        var ndItem = new this.nodeItem();
                        if (ndCode == this.options.rootcode) {
                            ndItem.nodecode = this.options.rootcode;
                            ndItem.nodetext = this.options.roottext;
                            ndItem.nodeurl = this.options.rooturl;
                            ndItem.iconcollapse = this.options.rooticon;
                        } else {
                            ndItem = this._methods._hsNodes[ndCode];
                        };

                        var eParams = {
                            treePlug: this,
                            nodeObject: $(node)[0],
                            nodeParams: ndItem
                        };
                        nodeClickEvent.call(null, eParams);
                    } catch (error) {
                        alert("控件單擊事件執行錯誤!" + error);
                    }
                };
            },

            // @ method: _onNodeDblClick() 執行節點自定雙擊事件
            // @ depict: 執行節點自定雙擊事件
            // @ params: [object] node 樹節點DOM對象
            // @ pbtype: 內部調用方法
            _onNodeDblClick: function (node) {
                if (!node) { return; };
                var nodeDblClickEvent = this.options.nodedblclick;
                if (typeof (nodeDblClickEvent) != 'function') { nodeDblClickEvent = $.strToFunction(nodeDblClickEvent); };
                if (typeof (nodeDblClickEvent) == 'function') {
                    try {
                        var ndCode = $(node).attr("id").replace(this.myFnId + "_sdptree_node_span_", "");
                        var ndItem = new this.nodeItem();
                        if (ndCode == this.options.rootcode) {
                            ndItem.nodecode = this.options.rootcode;
                            ndItem.nodetext = this.options.roottext;
                            ndItem.nodeurl = this.options.rooturl;
                            ndItem.iconcollapse = this.options.rooticon;
                        } else {
                            ndItem = this._methods._hsNodes[ndCode];
                        };
                        var eParams = {
                            treePlug: this,
                            nodeObject: $(node)[0],
                            nodeParams: ndItem
                        };
                        nodeDblClickEvent.call(null, eParams);
                    } catch (error) {
                        alert("控件雙擊事件執行錯誤!" + error);
                    }
                };
            },

            // @ method: _onNodeCheckedChange() 執行節點自定選擇(選中狀態)改變事件
            // @ depict: 執行節點自定選擇(選中狀態)改變事件
            // @ params: [object] node 樹節點DOM對象
            // @ pbtype: 內部調用方法
            _onNodeCheckedChange: function (node) {
                if (!node) { return; };
                var nodeCheckedChange = this.options.checkedchange;
                if (typeof (nodeCheckedChange) != 'function') { nodeCheckedChange = $.strToFunction(nodeCheckedChange); };
                if (typeof (nodeCheckedChange) == 'function') {
                    try {
                        var ndCode = $(node).attr("id").replace(this.myFnId + "_sdptree_node_span_", "");
                        var ndItem = new this.nodeItem();
                        if (ndCode == this.options.rootcode) {
                            ndItem.nodecode = this.options.rootcode;
                            ndItem.nodetext = this.options.roottext;
                            ndItem.nodeurl = this.options.rooturl;
                            ndItem.iconcollapse = this.options.rooticon;
                        } else {
                            ndItem = this._methods._hsNodes[ndCode];
                        };
                        var eParams = {
                            treePlug: this,
                            nodeObject: $(node)[0],
                            nodeParams: ndItem
                        };
                        nodeCheckedChange.call(null, eParams);
                    } catch (error) {
                        alert("控件雙擊事件執行錯誤!" + error);
                    }
                };
            },

            _methods: {
                _fnObject: null,
                _myObject: null,
                _myContainer: null,
                _myFnId: "",
                _sdpTree: null,
                _myNodes: [],
                _hsNodes: null,
                _dtNodes: null,
                _createTree: function () {    // 建立樹HTML對象
                    // 初始化變量參數
                    this._sdpTree.empty();       // 清空目錄樹內的全部內容
                    this._fnObject.focusNodeCode = "";
                    this._myNodes = [];
                    this._hsNodes = new $.Hashtable();
                    this._dtNodes = [];
                    var _tmNodes = [], F = this._fnObject, P = this._fnObject.options, _this = this;

                    // 重組目錄節點(依次將全部的節點組成本身的樹) 一次循環完成 提升效率
                    function Renew_GroupNodes(currNodes) {
                        // 重繪節點上下級關係
                        function Renew_Tree(reNode) {
                            if (_tmNodes[reNode.nodecode]) {
                                for (var n = 0; n < _tmNodes[reNode.nodecode].length; n++) {
                                    reNode._childs[n] = _tmNodes[reNode.nodecode][n];
                                    reNode._childs[n]._parent = reNode;
                                    reNode._childs[n]._firstFlag = (n == 0) ? true : false;
                                    reNode._childs[n]._lastFlag = (n == (_tmNodes[reNode.nodecode].length - 1)) ? true : false;
                                    reNode._childs[n]._haveChild = (_tmNodes[_tmNodes[reNode.nodecode][n].nodecode]) ? true : false;
                                    reNode._childs[n]._nodeLevel = reNode._nodeLevel + 1;
                                    Renew_Tree(_tmNodes[reNode.nodecode][n]);  // 迭代循環
                                }
                            }
                        };

                        var m = 0;
                        _tmNodes[P.rootcode] = [];   // 根節點
                        for (m = 0; m < currNodes.length; m++) {
                            var _nd = currNodes[m];
                            _tmNodes[_nd.supnodecode] = _tmNodes[_nd.supnodecode] || [];
                            _tmNodes[_nd.supnodecode].push(_nd);
                            _this._hsNodes.add(_nd.nodecode, _nd);
                        };
                        var _rtNodes = _tmNodes[P.rootcode];

                        for (m = 0; m < _rtNodes.length; m++) {
                            _this._dtNodes[m] = _rtNodes[m];
                            _this._dtNodes[m]._parent = null;
                            _this._dtNodes[m]._firstFlag = (m == 0) ? true : false;  // 設置參數
                            _this._dtNodes[m]._lastFlag = (m == (_rtNodes.length - 1)) ? true : false;
                            _this._dtNodes[m]._haveChild = (_tmNodes[_rtNodes[m].nodecode]) ? true : false;
                            _this._dtNodes[m]._nodeLevel = 1;
                            Renew_Tree(_rtNodes[m]);                               // 迭代循環
                        };

                        _rtNodes = null;
                        _tmNodes = null;
                    };

                    // 執行節點重組
                    Renew_GroupNodes(F.curNodes);
                    F.curNodes = [];  // 清空臨時節點數組變量,便於後續從新加載使用

                    // 定義前綴字符
                    var full_Prefix = this._myFnId + "_sdptree_node_full";     // 完整的一個節點DIV(包含:連線、+號圖片、節點圖片、選擇框、節點文本)
                    var node_Prefix = this._myFnId + "_sdptree_node_span";     // 節點SPAN
                    // var plus_Prefix = this._myFnId + "_sdptree_node_plus";     // + 號圖片
                    var nimg_Prefix = this._myFnId + "_sdptree_node_icon";     // 節點圖片
                    var chkr_Prefix = this._myFnId + "_sdptree_node_chk";      // 選擇圖片
                    var text_Prefix = this._myFnId + "_sdptree_node_text";     // 節點文本
                    var clip_Prefix = this._myFnId + "_sdptree_node_clip";     // 子節點DIV

                    // 注意點:前臺傳入的全部自定義的圖標,所有已是指定的完整路徑了,因此這裏就不須要轉換
                    var _rootCode = P.rootcode;
                    if (P.showroot) {           // 斷定是否顯示根節點
                        var tmRhtml = [];
                        tmRhtml.push('<div id="' + full_Prefix + '_' + _rootCode + '" stype="full" >');
                        tmRhtml.push('<span id="' + node_Prefix + '_' + _rootCode + '" class="node_default" stype="node" >');
                        if (P.showicon) {
                            tmRhtml.push('<span id="' + nimg_Prefix + '_' + _rootCode + '" stype="icon" ');
                            if (P.rooticon) {   // 是否客戶自定義的圖片
                                tmRhtml.push('class="custom_img" style="background-image: url(' + (P.rooticon) + ');"');
                            } else {                                // 啓用默認的樣式圖片
                                tmRhtml.push('class="root_img"');
                            };
                            tmRhtml.push(' ></span>');
                        };
                        if (P.selecttype == "checkbox") {     // 是否開啓選擇按鈕
                            tmRhtml.push('<span id="' + chkr_Prefix + '_' + _rootCode + '" stype="check" class="checkbox"></span>');
                        } else if (P.selecttype == "radio") {
                            tmRhtml.push('<span id="' + chkr_Prefix + '_' + _rootCode + '" stype="check" class="radiobtn"></span>');
                        };
                        tmRhtml.push('<span id="' + text_Prefix + '_' + _rootCode + '"  class="root_title" stype="text">' + P.roottext + '</span>');
                        tmRhtml.push('</span>');
                        tmRhtml.push('</div>');
                        this._sdpTree.append($(tmRhtml.join("")));
                        tmRhtml = null;
                    };
                    var $clipDom = null;
                    if (P.showroot) $clipDom = $('<div id="' + clip_Prefix + '_' + _rootCode + '" class="clipdiv" stype="clip" style="display: block" ></div>');
                    var _recHTML = this._createNodes(this._dtNodes);
                    if (_recHTML) {
                        if ($clipDom) { $clipDom.append($(_recHTML)); this._sdpTree.append($clipDom); } else { this._sdpTree.append($(_recHTML)); };
                    } else {
                        if ($clipDom) { this._sdpTree.append($clipDom); };
                    };
                    _recHTML = null;

                    // 綁定事件
                    this._bindEvent();
                    if (P.openall) { F.expandAll(); };
                },
                _createNodes: function (crNodes) { // 建立節點HTML
                    var full_Prefix = this._myFnId + "_sdptree_node_full";     // 完整的一個節點DIV(包含:連線、+號圖片、節點圖片、選擇框、節點文本)
                    var node_Prefix = this._myFnId + "_sdptree_node_span";     // 節點SPAN
                    var plus_Prefix = this._myFnId + "_sdptree_node_plus";     // + 號圖片
                    var nimg_Prefix = this._myFnId + "_sdptree_node_icon";     // 節點圖片
                    var chkr_Prefix = this._myFnId + "_sdptree_node_chk";      // 選擇圖片
                    var text_Prefix = this._myFnId + "_sdptree_node_text";     // 節點文本
                    var clip_Prefix = this._myFnId + "_sdptree_node_clip";     // 子節點DIV
                    var P = this._fnObject.options;                            // 參數變量

                    var tmHTML = [];
                    for (var m = 0; m < crNodes.length; m++) {
                        var crNode = crNodes[m];
                        tmHTML.push('<div id="' + full_Prefix + '_' + crNode.nodecode + '" stype="full" >');
                        var tmIndent = [];
                        var tmParent = crNode._parent;
                        var lv = crNode._nodeLevel;
                        while (lv > 1) { tmIndent[tmIndent.length] = tmParent; tmParent = tmParent._parent; lv--; };
                        for (lv = tmIndent.length - 1; lv >= 0; lv--) {
                            tmHTML.push('<span class="' + ((this._fnObject.options.showline == true) ? ((tmIndent[lv]._lastFlag == false) ? "node_line_10" : "nullimg") : "nullimg") + '" stype="line" ></span>');
                        };
                        tmIndent = null;
                        tmParent = null;
                        var tmNdCode = crNode.nodecode;
                        if (P.showline == true) {          // 二、節點自身圖標 + - 
                            if (crNode._haveChild) {
                                if (crNode._nodeLevel == 1 && P.showroot == false && crNode._firstFlag == true) {
                                    tmHTML.push('<span id="' + plus_Prefix + '_' + tmNdCode + '"  stype="plus" class="' + ((crNode._lastFlag) ? "node_plug_1l" : "node_plug_2b") + '"></span>');
                                } else {
                                    tmHTML.push('<span id="' + plus_Prefix + '_' + tmNdCode + '"  stype="plus" class="' + ((crNode._lastFlag) ? "node_plug_2t" : "node_plug_3a") + '"></span>');
                                };
                            } else {
                                if (crNode._nodeLevel == 1 && P.showroot == false && crNode._firstFlag == true) {
                                    tmHTML.push('<span class="' + ((crNode._lastFlag) ? "node_line_11" : "node_line_20") + '" stype="line" ></span>');
                                } else {
                                    tmHTML.push('<span class="' + ((crNode._lastFlag) ? "node_line_21" : "node_line_3n") + '" stype="line" ></span>');
                                };
                            };

                        } else {   // 不顯示線
                            var tmPlusStr = "stype=\"plus\" id=" + plus_Prefix + "_" + tmNdCode;
                            var tmLineStr = "stype=\"line\"";
                            tmHTML.push('<span class="' + ((crNode._haveChild == true) ? "node_plug_0n" : "nullimg") + '" ' + ((crNode._haveChild == true) ? tmPlusStr : tmLineStr) + ' ></span>');
                        };
                        tmHTML.push('<span id="' + node_Prefix + '_' + tmNdCode + '" class="node_default" stype="node" >');  // 三、添加節點相關

                        // 節點小圖標
                        if (P.showicon) {

                            // 節點圖標  根據每一個節點自身是否認義 若是沒有定義,再從OPTIONS 參數中查詢
                            var cur_CollapseIcon = ""; //                    iconexpand: "",  iconcollapse: ""
                            var cur_ExpandIcon = "";
                            if ($.isNull(crNode.iconcollapse) == false) {  // 斷定節點收縮時顯示的圖標
                                cur_CollapseIcon = crNode.iconcollapse;    // 默認顯示圖標[收縮]
                                cur_ExpandIcon = crNode.iconexpand;        // 展開顯示圖標[展開]
                            } else {
                                if (crNode._haveChild == true)             // 斷定是否有子節點
                                {
                                    if ($.isNull(P.middefticon) == false) {
                                        cur_CollapseIcon = P.middefticon;   // 中間節點收縮[總體自定]
                                        cur_ExpandIcon = P.midexpdicon;     // 中間節點展開[總體自定]
                                    }
                                } else {
                                    if ($.isNull(P.endnodeicon) == false) {
                                        cur_CollapseIcon = P.endnodeicon;   // 末級節點[總體自定]
                                        cur_ExpandIcon = "";
                                    }
                                }
                            };

                            // 節點圖片  
                            if ($.isNull(cur_CollapseIcon) == false) {
                                tmHTML.push('<span class="custom_img" id="' + nimg_Prefix + '_' + tmNdCode + '" stype="icon" collimg="' + cur_CollapseIcon + '" expdimg="' + cur_ExpandIcon + '" style="background-image: url(' + cur_CollapseIcon + ');"></span>');
                            } else {
                                tmHTML.push('<span class="' + ((crNode._haveChild == true) ? "folder_collapse" : "folder_last") + '" id="' + nimg_Prefix + '_' + tmNdCode + '" stype="icon"></span>');
                            };
                        };
                        if (P.selecttype == "checkbox") {   // 容許添加選擇按鈕
                            tmHTML.push('<span id="' + chkr_Prefix + '_' + tmNdCode + '" stype="check" class="checkbox" ></span>');
                        } else if (P.selecttype == "radio") {
                            tmHTML.push('<span id="' + chkr_Prefix + '_' + tmNdCode + '" stype="check" class="radiobtn" ></span>');
                        };
                        tmHTML.push('<span id="' + text_Prefix + '_' + tmNdCode + '" class="node_title" stype="text">' + crNode.nodetext + '</span>');      //  節點名稱
                        tmHTML.push('</span>');
                        tmHTML.push('</div>');
                        if (crNode._childs.length > 0) {
                            tmHTML.push('<div id="' + clip_Prefix + '_' + tmNdCode + '" class="clipdiv" stype="clip"  style="display:none;" >');  // 第一級如下所有隱藏
                            tmHTML.push(this._createNodes(crNode._childs));
                            tmHTML.push('</div>');
                        };
                    };
                    return tmHTML.join("");
                },
                _updateNode: function (nodeCode) {            //  更新節點顯示樣式
                    var tmNowNode = this._hsNodes[nodeCode];  //  當前節點的Node數據
                    if (!tmNowNode) { return; };

                    // 一、首先更新本身
                    var nowFullNode = $(this._fnObject.getNode(nodeCode));                                       // 完整的節點對象
                    var nowSpanNode = nowFullNode.find("#" + this._myFnId + "_sdptree_node_span_" + nodeCode);   // 節點NODESPAN
                    var nowPlusSpan = nowSpanNode.prev();                                                        // 節點Plus + - 圖標
                    var nowIconSpan = nowFullNode.find("#" + this._myFnId + "_sdptree_node_icon_" + nodeCode);   // 節點ICON 圖標

                    var tmIndent = null, tmParent = null, lv = null, lineClass = "", tmI = 0;
                    if (!tmNowNode._haveChild) {  // 無子節點
                        // (1)、更新Plus
                        nowPlusSpan.removeAttr("id").removeAttr("open").attr("stype", "line");
                        if (this._fnObject.options.showline == true) {  // 顯示鏈接線
                            var lineClassName = "";
                            if (tmNowNode._nodeLevel == 1 && this._fnObject.options.showroot == false && tmNowNode._firstFlag == true) {
                                lineClassName = (tmNowNode._lastFlag) ? "node_line_11" : "node_line_20";
                            } else {
                                lineClassName = (tmNowNode._lastFlag) ? "node_line_21" : "node_line_3n";
                            };
                            nowPlusSpan.attr("class", lineClassName); // 更新樣式ClassName
                        } else {  // 不顯示鏈接線
                            nowPlusSpan.attr("class", "nullimg");
                        };
                        // (2)、更新Icon
                        if (nowIconSpan.length > 0) {
                            if (!nowIconSpan.hasClass("custom_img")) { nowIconSpan.attr("class", "folder_last"); };
                        };

                        // (3)、更新Line
                        tmIndent = [];
                        tmParent = tmNowNode._parent;
                        lv = tmNowNode._nodeLevel;
                        while (lv > 1) { tmIndent[tmIndent.length] = tmParent; tmParent = tmParent._parent; lv--; };
                        lineClass = "", tmI = 0;
                        for (lv = tmIndent.length - 1; lv >= 0; lv--) {
                            lineClass = ((this._fnObject.options.showline == true) ? ((tmIndent[lv]._lastFlag == false) ? "node_line_10" : "nullimg") : "nullimg");
                            $(nowFullNode[0].childNodes[tmI]).attr("class", lineClass);
                            tmI++;
                        };

                        tmIndent = null;
                        tmParent = null;
                        lineClass = null;
                    } else {    // 有子節點
                        // (1)、更新Plus
                        var nowClipDiv = this._sdpTree.find("#" + this._myFnId + "_sdptree_node_clip_" + nodeCode);
                        var isOpen = (nowClipDiv.css("display") == "none") ? false : true;
                        nowPlusSpan.attr("id", this._myFnId + "_sdptree_node_plus_" + nodeCode).attr("stype", "plus");
                        if (isOpen) { nowPlusSpan.attr("open", true); } else { nowPlusSpan.attr("open", false); };  // 設置展開狀態
                        if (this._fnObject.options.showline == true) {  // 顯示鏈接線
                            var plusClassName = "";
                            if (tmNowNode._nodeLevel == 1 && this._fnObject.options.showroot == false && tmNowNode._firstFlag == true) {
                                plusClassName = (tmNowNode._lastFlag) ? "node_plug_1l" : "node_plug_2b";
                            } else { plusClassName = (tmNowNode._lastFlag) ? "node_plug_2t" : "node_plug_3a"; };
                            nowPlusSpan.attr("class", plusClassName);               // 設置Plus 收縮樣式
                            if (isOpen) {
                                switch (plusClassName) {
                                    case "node_plug_1l":
                                        nowPlusSpan.addClass("node_expd_1l");
                                        break;
                                    case "node_plug_2b":
                                        nowPlusSpan.addClass("node_expd_2b");
                                        break;
                                    case "node_plug_2t":
                                        nowPlusSpan.addClass("node_expd_2t");
                                        break;
                                    case "node_plug_3a":
                                        nowPlusSpan.addClass("node_expd_3a");
                                        break;
                                };
                            };
                        } else {  // 不顯示鏈接線
                            nowPlusSpan.attr("class", "node_plug_0n");              // 設置Plus 收縮樣式
                            if (isOpen) nowPlusSpan.addClass("node_expd_0n");       // 添加Plus 展開樣式
                        };

                        // (2)、更新Icon
                        if (nowIconSpan.length > 0) {
                            if (!nowIconSpan.hasClass("custom_img")) {
                                nowIconSpan.attr("class", "folder_collapse");            // 設置Icon 收縮樣式 
                                if (isOpen) {                                            // 添加Icon 展開樣式
                                    nowIconSpan.addClass("folder_expand");
                                };
                            };
                        };

                        // (3)、更新Line
                        tmIndent = [];
                        tmParent = tmNowNode._parent;
                        lv = tmNowNode._nodeLevel;
                        while (lv > 1) { tmIndent[tmIndent.length] = tmParent; tmParent = tmParent._parent; lv--; };
                        lineClass = "", tmI = 0;
                        for (lv = tmIndent.length - 1; lv >= 0; lv--) {
                            lineClass = ((this._fnObject.options.showline == true) ? ((tmIndent[lv]._lastFlag == false) ? "node_line_10" : "nullimg") : "nullimg");
                            $(nowFullNode[0].childNodes[tmI]).attr("class", lineClass);
                            tmI++;
                        };

                        tmIndent = null;
                        tmParent = null;
                        lineClass = null;
                    };

                    // 二、其次更新下級
                    if (tmNowNode._haveChild) {
                        for (var tm2 = 0; tm2 < tmNowNode._childs.length; tm2++) {
                            var tmSubNodeCode = tmNowNode._childs[tm2].nodecode;
                            this._updateNode(tmSubNodeCode); // 迭代循環更新子節點
                        };
                    };
                },

                // @ params: [bool]   isOpAll   是否所有 說明:前面調用時候,根據狀況 是否執行所有節點的標誌(通常使用於所有選中、取消選擇使用)
                _checkedNodes: function (node, bool, isOpAll) {        // 設置多節點選中狀態
                    this._checkedNode(node, bool);                     // 設置當前節點
                    if (this._fnObject.options.cascade || isOpAll) {   // 級聯選擇節點 或 前臺必需要所有節點
                        var tm_Prefix = this._myFnId + "_sdptree_node_chk_";
                        var tm_NodeCode = node.attr("id").replace(tm_Prefix, "");
                        var tm_Flag = true;
                        if ((bool) && (tm_NodeCode != this._fnObject.options.rootcode)) {
                            var tm_pNodeCode = this._hsNodes[tm_NodeCode].supnodecode;      // 設置上級勾選
                            while (tm_Flag) {
                                var pNode = this._sdpTree.find("#" + tm_Prefix + tm_pNodeCode);
                                if (tm_pNodeCode == this._fnObject.options.rootcode) {
                                    if (!pNode.prop("checked")) { this._checkedNode(pNode, true); };
                                    tm_Flag = false;
                                    break;
                                } else {
                                    if (!pNode.prop("checked")) { this._checkedNode(pNode, true); };
                                    tm_pNodeCode = this._hsNodes[tm_pNodeCode].supnodecode;
                                };
                            };
                        };

                        // 設置下級勾選
                        var subNodes = null;
                        if (tm_NodeCode == this._fnObject.options.rootcode) { subNodes = this._dtNodes; } else { subNodes = this._hsNodes[tm_NodeCode]._childs; };
                        this._checkedSubNodes(subNodes, bool);
                        subNodes = null;
                    };
                },
                _checkedNode: function (node, bool) {
                    node.removeClass("checkbox").removeClass("checkbox_check").addClass(((bool) ? "checkbox_check" : "checkbox")).prop("checked", bool);
                },
                _checkedSubNodes: function (nodes, bool) {
                    if (!nodes) { return; };
                    for (var tm1 = 0; tm1 < nodes.length; tm1++) {
                        var tm_Node = this._sdpTree.find("#" + this._myFnId + "_sdptree_node_chk_" + nodes[tm1].nodecode);
                        if (tm_Node.length > 0) {
                            this._checkedNode(tm_Node, bool);
                            if (nodes[tm1]._childs) { this._checkedSubNodes(nodes[tm1]._childs, bool); };
                        };
                    };
                },
                _removeHashNodes: function (nodeCode) {
                    var rmNode = this._hsNodes[nodeCode];
                    if (!rmNode) { return; };
                    if (rmNode._haveChild) {
                        for (var tm2 = 0; tm2 < rmNode._childs.length; tm2++) {
                            this._removeHashNodes(rmNode._childs[tm2].nodecode);
                        };
                    };

                    this._hsNodes.remove(nodeCode);
                },
                _bindEvent: function () {
                    var this_myNodes = this._sdpTree.find("span[stype='node']");
                    var this_treeID = this._myFnId;
                    var this_rootNode = this._sdpTree.find("#" + this_treeID + "_sdptree_node_span_" + this._fnObject.options.rootcode);
                    var _this = this;

                    if (this_rootNode.length > 0) {
                        this_rootNode.hover(function () {
                            $(this).addClass("node_hover").attr("title", $.text(this));
                        }, function () {
                            $(this).removeClass("node_hover").attr("title", "");
                        });
                    };
                    if (this_myNodes.length == 0) { return; };
                    this_myNodes.hover(function () {   // 性能比較 此方法直接綁定hover 比 $().each() 方法耗時少不少
                        var tmThisNode = _this._hsNodes[$(this).attr("id").replace(this_treeID + "_sdptree_node_span_", "")];
                        var tmTitle = "";
                        if (tmThisNode) { tmTitle = tmThisNode.nodetitle; };
                        if (!tmTitle) { tmTitle = $.text(this); };
                        $(this).addClass("node_hover").attr("title", tmTitle);
                    }, function () {
                        $(this).removeClass("node_hover").attr("title", "");
                    });
                }
            }
        };
    };
})(jQuery);
View Code

 

       第五:網頁端頁面代碼也貼出來

 

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
    <title>樹 Tree </title>
    <meta http-equiv="Content-Type" content="text/html; charset=UTF-8" />
    <meta http-equiv="X-UA-Compatible" content="IE=edge" />
    <link href="css/tree.css" rel="stylesheet" type="text/css" />
    <script src="js/min-jquery-1.9.1.js" type="text/javascript"></script>
    <script src="js/basic.js" type="text/javascript"></script>
    <script src="js/tree_plug.js" type="text/javascript"></script>
    <script type="text/javascript">

        var nodesJson = {};
        var nodesXml = "";

        // 定義一個Tree插件實例對象變量
        var treePlug = null;

        // 加載 Tree
        function onLoadTree() {

            // 建立一個Tree插件實例
            treePlug = new $.fn.webTree();

            // 初始化插件對象內部參數
            treePlug.init($("div.sdp-tree"));

            var ndItem = null;
            for (var i = 10; i < 20; i++) {

                // 第一級節點
                ndItem = {
                    nodecode: String(i),
                    nodetext: "第一節點" + i,
                    nodetitle: "",
                    supnodecode: ""

                };
                treePlug.addNodeItem(ndItem);

                // 第二級節點
                for (var j = 10; j < 20; j++) {
                    ndItem = {
                        nodecode: String(i) + String(j),
                        nodetext: "第二節點" + String(i) + String(j),
                        nodetitle: "",
                        supnodecode: String(i)
                    };
                    treePlug.addNodeItem(ndItem);

                    // 第三級節點
                    for (var k = 10; k < 20; k++) {
                        var tmCode = String(i) + String(j) + String(k);
                        ndItem = {
                            nodecode: tmCode,
                            nodetext: "第二節點" + tmCode,
                            nodetitle: "",
                            supnodecode: String(i) + String(j)
                        };
                        treePlug.addNodeItem(ndItem);
                    }
                }

            };

            treePlug.makeTree();

        }

   
    </script>
</head>
<body>
    <div style="position: absolute; display: block; top: 10px; left: 50px;">
        <button onclick="onLoadTree()">
            加載目錄樹</button>
    </div>
    <div class="sdp-tree" id="demo_tree" style="position: absolute; display: block; left: 50px;
        top: 50px; height: 500px; width: 400px;">
    </div>
</body>
</html>
View Code

 

       第六:最終顯示效果

 

     第七:補充將Js補充上來   basic.js

(function ($) {
    $.extend({
        replaceAll: function (str, s1, s2) {
            if (str) {
                return str.replace(new RegExp(s1, "gm"), s2)
            } else {
                return str
            }
        },
        Hashtable: function () {
            Hash = function () { };
            Hash.prototype = {
                constructor: Hash,
                add: function (oKey, oVal) {
                    if (!this.hasOwnProperty(oKey)) {
                        this[oKey] = oVal
                    }
                },
                count: function () {
                    var _count = 0;
                    for (var iCount in this) {
                        if (this.hasOwnProperty(iCount)) {
                            _count++
                        }
                    };
                    return _count
                },
                remove: function (oKey) {
                    if (this.hasOwnProperty(oKey)) {
                        delete this[oKey]
                    }
                },
                update: function (oKey, oVal) {
                    this[oKey] = oVal
                },
                has: function (oKey) {
                    var type = typeof oKey;
                    if (type === 'string' || type === 'number') {
                        return this.hasOwnProperty(oKey)
                    } else if (type === 'function' && this.some(oKey)) {
                        return true
                    };
                    return false
                },
                clear: function () {
                    for (var oKey in this) {
                        if (this.hasOwnProperty(oKey)) {
                            delete this[oKey]
                        }
                    }
                },
                isempty: function () {
                    for (var oKey in this) {
                        if (this.hasOwnProperty(oKey)) {
                            return false
                        }
                    };
                    return true
                },
                each: function (fn) {
                    for (var oKey in this) {
                        if (this.hasOwnProperty(oKey)) {
                            fn.call(this, this[oKey], oKey, this)
                        }
                    }
                },
                map: function (fn) {
                    var hash = new Hash;
                    for (var oKey in this) {
                        if (this.hasOwnProperty(oKey)) {
                            hash.add(oKey, fn.call(this, this[oKey], oKey, this))
                        }
                    };
                    return hash
                },
                join: function (split) {
                    split = split !== undefined ? split : ',';
                    var rst = [];
                    this.each(function (oVal) {
                        rst.push(oVal)
                    });
                    return rst.join(split)
                },
                every: function (fn) {
                    for (var oKey in this) {
                        if (this.hasOwnProperty(oKey)) {
                            if (!fn.call(this, this[oKey], oKey, this)) {
                                return false
                            }
                        }
                    };
                    return true
                },
                some: function (fn) {
                    for (var oKey in this) {
                        if (this.hasOwnProperty(oKey)) {
                            if (fn.call(this, this[oKey], oKey, this)) {
                                return true
                            }
                        }
                    };
                    return false
                },
                find: function (oKey) {
                    var type = typeof oKey;
                    if (type === 'string' || type === 'number' && this.has(oKey)) {
                        return this[oKey]
                    } else if (type === 'function') {
                        for (var _oKey in this) {
                            if (this.hasOwnProperty(_oKey) && oKey.call(this, this[_oKey], _oKey, this)) {
                                return this[_oKey]
                            }
                        }
                    };
                    return null
                }
            };
            return new Hash()
        },
        isNull: function (objVal) {
            if (typeof (objVal) == "undefined" || objVal == null) {
                return true
            };
            if (typeof (objVal) == "number" || typeof (objVal) == "boolean") {
                return false
            };
            if (objVal == "") {
                return true
            };
            try {
                if (objVal.length == 0) {
                    return true
                };
                var strComp = $.replaceAll(String(objVal), " ", "");
                if (strComp == "" || strComp == "&nbsp;" || strComp.length == 0) {
                    return true
                } else {
                    return false
                }
            } catch (error) {
                return false
            }
        },
        isNumber: function (obj) {
            return (!isNaN(obj) && typeof (obj) == "number")
        },
        newGuid: function () {
            function S4() {
                return (((1 + Math.random()) * 0x10000) | 0).toString(16).substring(1)
            };
            return (S4() + S4() + "-" + S4() + "-" + S4() + "-" + S4() + "-" + S4() + S4() + S4()).toUpperCase()
        },
        loadXmlFile: function (xmlFilePath) {
            var retXmlDoc = null;
            if (xmlFilePath) {
                $.ajax({
                    type: 'GET',
                    async: false,
                    url: xmlFilePath,
                    dataType: 'xml',
                    success: function (xmlData) {
                        retXmlDoc = xmlData
                    }
                })
            };
            return retXmlDoc
        },
        loadXmlString: function (xmlStr) {
            var retXmlDoc = null;
            if (xmlStr) {
                try {
                    retXmlDoc = $.parseXML(xmlStr)
                } catch (g) {
                    retXmlDoc = null
                }
            };
            return retXmlDoc
        },
        stopBubble: function (event) {
            event = event || window.event;
            $.preventDefault(event);
            $.stopPropagation(event);
            return false
        },
        preventDefault: function (event) {
            event = event || window.event;
            if (event.preventDefault) {
                event.preventDefault()
            };
            event.returnValue = false
        },
        stopPropagation: function (event) {
            event = event || window.event;
            if (event.stopPropagation) {
                event.stopPropagation()
            };
            event.cancelBubble = true
        },
        runStrEvent: function (strEvent, e) {
            var retEventValue = null;
            if (!strEvent) {
                return retEventValue
            };
            var _runEvent = $.strToFunction(strEvent);
            if (typeof (_runEvent) == 'function') {
                try {
                    retEventValue = _runEvent.call(null, e)
                } catch (err) {
                    retEventValue = err
                }
            } else {
                alert("錯誤:事件方法有誤!" + strEvent);
                retEventValue = "ERROR:事件方法有誤!"
            };
            if (typeof (retEventValue) == 'undefined') {
                retEventValue = null
            };
            return retEventValue
        },
        strToFunction: function (strEvent) {
            if (typeof (strEvent) == "function") {
                return strEvent
            } else if (!strEvent || typeof (strEvent) != "string") {
                return null
            } else {
                try {
                    strEvent = $.trim(String(strEvent));
                    if (strEvent.indexOf('(') > 0) {
                        strEvent = strEvent.substring(0, strEvent.indexOf('('))
                    };
                    return (new Function("return " + strEvent))()
                } catch (error) {
                    return null
                }
            }
        },
        getJSON_FromFile: function (filePath) {
            var jsonObj = null;
            if (filePath) {
                $.ajaxSettings.async = false;
                $.getJSON(filePath,
                function (retData) {
                    jsonObj = retData
                });
                $.ajaxSettings.async = true
            };
            return jsonObj
        },
        getJSON_FromStr: function (jsonStr) {
            var jsonObj = null;
            if (jsonStr) {
                try {
                    jsonObj = $.parseJSON(jsonStr)
                } catch (error) {
                    jsonObj = null
                }
            };
            return jsonObj
        }

    });
})(jQuery);
View Code

 

     第八:由於沒法上傳附件,因此只能提供外部連接地址:  Tree_Demo.rar

相關文章
相關標籤/搜索