道非道 非常道

          勤思、謹(jǐn)言、慎行、厚積、薄發(fā)

          統(tǒng)計(jì)

          web

          天圓

          經(jīng)濟(jì) 政治 軍事

          鍵康

          xtree.js

            1 
            2 /*----------------------------------------------------------------------------\
            3 |                       Cross Browser Tree Widget 1.17                        |
            4 |-----------------------------------------------------------------------------|
            5 |                          Created by Emil A Eklund                           |
            6 |                  (http://webfx.eae.net/contact.html#emil)                   |
            7 |                      For WebFX (http://webfx.eae.net/)                      |
            8 |-----------------------------------------------------------------------------|
            9 | An object based tree widget,  emulating the one found in microsoft windows, |
           10 | with persistence using cookies. Works in IE 5+, Mozilla and konqueror 3.    |
           11 |-----------------------------------------------------------------------------|
           12 |          Copyright (c) 2000, 2001, 2002, 2003, 2006 Emil A Eklund           |
           13 |-----------------------------------------------------------------------------|
           14 | Licensed under the Apache License, Version 2.0 (the "License"); you may not |
           15 | use this file except in compliance with the License.  You may obtain a copy |
           16 | of the License at http://www.apache.org/licenses/LICENSE-2.0                |
           17 | - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - |
           18 | Unless  required  by  applicable law or  agreed  to  in  writing,  software |
           19 | distributed under the License is distributed on an  "AS IS" BASIS,  WITHOUT |
           20 | WARRANTIES OR  CONDITIONS OF ANY KIND,  either express or implied.  See the |
           21 | License  for the  specific language  governing permissions  and limitations |
           22 | under the License.                                                          |
           23 |-----------------------------------------------------------------------------|
           24 | Dependencies: xtree.css (To set up the CSS of the tree classes)             |
           25 |-----------------------------------------------------------------------------|
           26 | 2001-01-10 | Original Version Posted.                                       |
           27 | 2001-03-18 | Added getSelected and get/setBehavior  that can make it behave |
           28 |            | more like windows explorer, check usage for more information.  |
           29 | 2001-09-23 | Version 1.1 - New features included  keyboard  navigation (ie) |
           30 |            | and the ability  to add and  remove nodes dynamically and some |
           31 |            | other small tweaks and fixes.                                  |
           32 | 2002-01-27 | Version 1.11 - Bug fixes and improved mozilla support.         |
           33 | 2002-06-11 | Version 1.12 - Fixed a bug that prevented the indentation line |
           34 |            | from  updating correctly  under some  circumstances.  This bug |
           35 |            | happened when removing the last item in a subtree and items in |
           36 |            | siblings to the remove subtree where not correctly updated.    |
           37 | 2002-06-13 | Fixed a few minor bugs cased by the 1.12 bug-fix.              |
           38 | 2002-08-20 | Added usePersistence flag to allow disable of cookies.         |
           39 | 2002-10-23 | (1.14) Fixed a plus icon issue                                 |
           40 | 2002-10-29 | (1.15) Last changes broke more than they fixed. This version   |
           41 |            | is based on 1.13 and fixes the bugs 1.14 fixed withou breaking |
           42 |            | lots of other things.                                          |
           43 | 2003-02-15 | The  selected node can now be made visible even when  the tree |
           44 |            | control  loses focus.  It uses a new class  declaration in the |
           45 |            | css file '.webfx-tree-item a.selected-inactive', by default it |
           46 |            | puts a light-gray rectangle around the selected node.          |
           47 | 2003-03-16 | Adding target support after lots of lobbying                |
           48 | 2006-05-26 | Changed license to Apache Software License 2.0.                |
           49 |-----------------------------------------------------------------------------|
           50 | Created 2000-12-11 | All changes are in the log above. | Updated 2006-05-26 |
           51 \----------------------------------------------------------------------------*/
           52 
           53 // tree config 對(duì)象,設(shè)定框架的基本信息。
           54 var webFXTreeConfig = {
           55     rootIcon        : 'images/foldericon.png',
           56     openRootIcon    : 'images/openfoldericon.png',
           57     folderIcon      : 'images/foldericon.png',
           58     openFolderIcon  : 'images/openfoldericon.png',
           59     fileIcon        : 'images/file.png',
           60     iIcon           : 'images/I.png',
           61     lIcon           : 'images/L.png',
           62     lMinusIcon      : 'images/Lminus.png',
           63     lPlusIcon       : 'images/Lplus.png',
           64     tIcon           : 'images/T.png',
           65     tMinusIcon      : 'images/Tminus.png',
           66     tPlusIcon       : 'images/Tplus.png',
           67     blankIcon       : 'images/blank.png',
           68     defaultText     : 'Tree Item',
           69     defaultAction   : 'javascript:void(0);',
           70     defaultBehavior : 'classic',
           71     //默認(rèn)是否打開樹的根節(jié)點(diǎn)。
           72     usePersistence    : true
           73 };
           74 
           75 // tree handler 對(duì)象,設(shè)定常用的值和方法。
           76 var webFXTreeHandler = {
           77     idCounter : 0,
           78     idPrefix  : "webfx-tree-object-",
           79     all       : {},
           80     behavior  : null,
           81     selected  : null,
           82     onSelect  : null/* should be part of tree, not handler */
           83     getId     : function() { return this.idPrefix + this.idCounter++; },
           84     toggle    : function (oItem) { this.all[oItem.id.replace('-plus','')].toggle(); },
           85     select    : function (oItem) { this.all[oItem.id.replace('-icon','')].select(); },
           86     // 當(dāng)節(jié)點(diǎn)得到焦點(diǎn)時(shí),使id的元素執(zhí)行  focus(),節(jié)點(diǎn)方法。
           87     focus     : function (oItem) { this.all[oItem.id.replace('-anchor','')].focus(); },
           88     blur      : function (oItem) { this.all[oItem.id.replace('-anchor','')].blur(); },
           89     keydown   : function (oItem, e) { return this.all[oItem.id].keydown(e.keyCode); },
           90     cookies   : new WebFXCookie(),
           91     insertHTMLBeforeEnd    :    function (oElement, sHTML) {
           92         // 當(dāng)可以用 insertAdjacentHTML 方法時(shí)
           93         if (oElement.insertAdjacentHTML != null) {
           94             //sHTML插件 oElement 結(jié)束標(biāo)簽前
           95             oElement.insertAdjacentHTML("BeforeEnd", sHTML)
           96             return;
           97         }
           98         //當(dāng)不可以用 insertAdjacentHTML 方法時(shí)
           99         var df;    // DocumentFragment
          100         var r = oElement.ownerDocument.createRange();
          101         r.selectNodeContents(oElement);
          102         r.collapse(false);
          103         df = r.createContextualFragment(sHTML);
          104         oElement.appendChild(df);
          105     }
          106 };
          107 
          108 
          109 /*
          110  * WebFXCookie class
          111  * cookie 操作類
          112  */
          113 function WebFXCookie() {
          114     if (document.cookie.length) { this.cookies = ' ' + document.cookie; }
          115 }
          116 
          117 //給 cookie 賦值,方法
          118 WebFXCookie.prototype.setCookie = function (key, value) {
          119     // 給 cookie 賦值方式,后面沒有指定失效日期,
          120     // 則瀏覽器默認(rèn)是在關(guān)閉瀏覽器(也就是關(guān)閉所有窗口)之后過期。
          121     //escape()  方法是把字符串按 URL 編碼方法來編碼的
          122     document.cookie = key + "=" + escape(value);
          123 }
          124 /**
          125  * @function 返回 cookie  中存儲(chǔ)著 key的值。
          126  * 1.找到關(guān)鍵字在 cookies 中存儲(chǔ)的位置
          127  * 2.判斷存儲(chǔ)位署 start 是否為-1,如果為-1表示不存在返回null
          128  * 3.檢索start位置到';'的第一個(gè)位置,并賦予變量 end
          129  * 4.如果 end =-1 ,表示不存在,則把 cookies 的長度賦予它
          130  * 5.end -= start ,計(jì)算出關(guān)鍵字key 的長度.
          131  * 6.使用 substr 方法 從起始索引號(hào)提取字符串中指定數(shù)目的字符。
          132  * 7.提取'='后至字符串長度減去  '=' 的位置。
          133  */
          134 WebFXCookie.prototype.getCookie = function (key) {
          135     if (this.cookies) {
          136         var start = this.cookies.indexOf(' ' + key + '=');
          137         if (start == -1) { return null; }
          138         var end = this.cookies.indexOf(";", start);
          139         if (end == -1) { end = this.cookies.length; }
          140         end -= start;
          141         var cookie = this.cookies.substr(start,end);
          142       // unescqpe 方法,處理從cookie 接收過來的值,并按 URL編碼格式轉(zhuǎn)換成字符串。
          143         return unescape(cookie.substr(cookie.indexOf('=') + 1, cookie.length - cookie.indexOf('=') + 1));
          144     }
          145     else { return null; }
          146 }
          147 
          148 
          149 
          150 /*
          151  * WebFXTreeAbstractNode class
          152  * tree 抽象節(jié)點(diǎn)類
          153  */
          154 function WebFXTreeAbstractNode(sText, sAction) {
          155     this.childNodes  = [];
          156     this.id     = webFXTreeHandler.getId();
          157     this.text   = sText || webFXTreeConfig.defaultText;
          158     this.action = sAction || webFXTreeConfig.defaultAction;
          159     this._last  = false;
          160     webFXTreeHandler.all[this.id] = this;
          161 }
          162 
          163 /*
          164  * To speed thing up if you're adding multiple nodes at once (after load)
          165  * use the bNoIdent parameter to prevent automatic re-indentation and call
          166  * the obj.ident() method manually once all nodes has been added.
          167  */
          168 /**
          169  * @function WebFXTreeAbstractNode 類的 add 方法 .
          170  * @param node 節(jié)點(diǎn), bNoIdent 
          171  */
          172 WebFXTreeAbstractNode.prototype.add = function (node, bNoIdent) {
          173     //將this 對(duì)象賦予  node 節(jié)點(diǎn)的父節(jié)點(diǎn)。
          174     node.parentNode = this;
          175     //this 節(jié)點(diǎn)的添加一個(gè)節(jié)點(diǎn)是 node 節(jié)點(diǎn)。
          176     this.childNodes[this.childNodes.length] = node;
          177     // 變量 root  節(jié)點(diǎn),由 this 賦予
          178     var root = this;
          179     //為什么是2呢?因?yàn)?nbsp; 節(jié)點(diǎn)下標(biāo)從 0開始數(shù),并且要去掉它本身這個(gè)節(jié)點(diǎn)。
          180     if (this.childNodes.length >= 2) {
          181         this.childNodes[this.childNodes.length - 2]._last = false;
          182     }
          183     // root 變量成為根節(jié)點(diǎn)
          184     while (root.parentNode) { 
          185         root = root.parentNode;
          186     }
          187     //如果樹已經(jīng)顯示
          188     if (root.rendered) {
          189         if (this.childNodes.length >= 2) {
          190             //document.getElementById(this.childNodes[this.childNodes.length - 2].id + '-plus').src = ((this.childNodes[this.childNodes.length -2].folder)?((this.childNodes[this.childNodes.length -2].open)?webFXTreeConfig.tMinusIcon:webFXTreeConfig.tPlusIcon):webFXTreeConfig.tIcon);
          191             //判斷應(yīng)該顯示的圖片。
          192             if(this.childNodes[this.childNodes.length -2].folder){
          193                 var _icon ;
          194                 if(this.childNodes[this.childNodes.length -2].open){
          195                   _icon = webFXTreeConfig.tMinusIcon;
          196                 }else{
          197                   _icon = webFXTreeConfig.tPlusIcon;
          198                 }
          199                 document.getElementById(this.childNodes[this.childNodes.length - 2].id + '-plus').src = _icon;
          200             }else{
          201               document.getElementById(this.childNodes[this.childNodes.length - 2].id + '-plus').src = webFXTreeConfig.tIcon;
          202             }
          203 
          204             this.childNodes[this.childNodes.length - 2].plusIcon = webFXTreeConfig.tPlusIcon;
          205             this.childNodes[this.childNodes.length - 2].minusIcon = webFXTreeConfig.tMinusIcon;
          206             this.childNodes[this.childNodes.length - 2]._last = false;
          207         }
          208         this._last = true;
          209         // 本節(jié)點(diǎn)賦予 foo對(duì)象
          210         var foo = this;
          211         while (foo.parentNode) {
          212             for (var i = 0; i < foo.parentNode.childNodes.length; i++) {
          213                 if (foo.id == foo.parentNode.childNodes[i].id) { 
          214                     break;
          215               }
          216             }
          217             if (i == foo.parentNode.childNodes.length - 1) { 
          218                 foo.parentNode._last = true
          219             }
          220             else { 
          221                 foo.parentNode._last = false
          222             }
          223             foo = foo.parentNode;
          224         }
          225         webFXTreeHandler.insertHTMLBeforeEnd(document.getElementById(this.id + '-cont'), node.toString());
          226         
          227         if ((!this.folder) && (!this.openIcon)) {
          228             this.icon = webFXTreeConfig.folderIcon;
          229             this.openIcon = webFXTreeConfig.openFolderIcon;
          230         }
          231         if (!this.folder) { 
          232             this.folder = true
          233             this.collapse(true); 
          234         }
          235         if (!bNoIdent) { 
          236             this.indent(); 
          237         }
          238     }
          239     return node;
          240 }
          241 /**
          242  *@function 擴(kuò)展/折疊 方法
          243  *1.判斷文件是否 折疊
          244  *2.如果狀態(tài)是打開,執(zhí)行 collapse ()方法 ,將其折疊
          245  *3.如果狀態(tài)是關(guān)閉,執(zhí)行 expand()  方法,將其打開
          246  */
          247 WebFXTreeAbstractNode.prototype.toggle = function() {
          248     if (this.folder) {
          249         if (this.open) {
          250              this.collapse();
          251       }
          252         else {
          253              this.expand(); 
          254         }
          255     }
          256 }
          257 /**
          258  *@function 節(jié)點(diǎn)選擇方法
          259  *當(dāng)選擇時(shí)此對(duì)象得到焦點(diǎn)
          260  */
          261 WebFXTreeAbstractNode.prototype.select = function() {
          262     document.getElementById(this.id + '-anchor').focus();
          263 }
          264 /**
          265  *@function 取消選擇方法
          266  *1.節(jié)點(diǎn)的className  為空
          267  *2.管理表示此節(jié)點(diǎn)未選擇
          268  */
          269 WebFXTreeAbstractNode.prototype.deSelect = function() {
          270     document.getElementById(this.id + '-anchor').className = '';
          271     webFXTreeHandler.selected = null;
          272 }
          273 /**
          274  *@function 當(dāng)節(jié)點(diǎn)被選中時(shí),執(zhí)行此得到焦點(diǎn)方法
          275  */
          276 WebFXTreeAbstractNode.prototype.focus = function() {
          277     // 如果選中為空,或者選中的不是本節(jié)點(diǎn),則執(zhí)行取消選擇方法。
          278     if ((webFXTreeHandler.selected) && (webFXTreeHandler.selected != this)) { 
          279          webFXTreeHandler.selected.deSelect(); 
          280     }
          281     //選擇值賦予本節(jié)點(diǎn)。
          282     webFXTreeHandler.selected = this;
          283     //改變圖標(biāo)
          284     if ((this.openIcon) && (webFXTreeHandler.behavior != 'classic')) { 
          285         document.getElementById(this.id + '-icon').src = this.openIcon; 
          286     }
          287     document.getElementById(this.id + '-anchor').className = 'selected';
          288     document.getElementById(this.id + '-anchor').focus();
          289     // 如果 onSelect 存在,則執(zhí)行本節(jié)點(diǎn)的  onSelect 方法。猜想:一種擴(kuò)展方法嗎???
          290     if (webFXTreeHandler.onSelect) { 
          291         webFXTreeHandler.onSelect(this); 
          292     }
          293 }
          294 
          295 WebFXTreeAbstractNode.prototype.blur = function() {
          296     if ((this.openIcon) && (webFXTreeHandler.behavior != 'classic')) { document.getElementById(this.id + '-icon').src = this.icon; }
          297     document.getElementById(this.id + '-anchor').className = 'selected-inactive';
          298 }
          299 
          300 /**
          301  * @function 節(jié)點(diǎn)擴(kuò)張方法的據(jù)體實(shí)體。
          302  */
          303 WebFXTreeAbstractNode.prototype.doExpand = function() {
          304     //改變節(jié)點(diǎn)的顯示圖標(biāo)。
          305     if (webFXTreeHandler.behavior == 'classic') { 
          306           document.getElementById(this.id + '-icon').src = this.openIcon; 
          307     }
          308     // 節(jié)點(diǎn)下的 div  層狀態(tài)為顯示
          309     if (this.childNodes.length) {  
          310           document.getElementById(this.id + '-cont').style.display = 'block';
          311   }
          312   // 改變節(jié)點(diǎn)的狀態(tài)為:打開
          313     this.open = true;
          314     //設(shè)定 存儲(chǔ)在 cookie 上id為 '1'
          315     if (webFXTreeConfig.usePersistence) {
          316         webFXTreeHandler.cookies.setCookie(this.id.substr(18,this.id.length - 18), '1');
          317      }
          318 }
          319 
          320 /**
          321  *@function 節(jié)點(diǎn)收縮的據(jù)體操作
          322  */
          323 WebFXTreeAbstractNode.prototype.doCollapse = function() {
          324     //改變節(jié)點(diǎn)的圖標(biāo)
          325     if (webFXTreeHandler.behavior == 'classic') { 
          326          document.getElementById(this.id + '-icon').src = this.icon; 
          327     }
          328     //改變 div 狀態(tài)為隱藏
          329     if (this.childNodes.length) { 
          330          document.getElementById(this.id + '-cont').style.display = 'none'; 
          331     }
          332     //改變節(jié)點(diǎn)當(dāng)前狀態(tài)是:關(guān)閉
          333     this.open = false;
          334     //設(shè)定 存儲(chǔ)在  cookie 上的id為‘0’
          335     if (webFXTreeConfig.usePersistence) {
          336         webFXTreeHandler.cookies.setCookie(this.id.substr(18,this.id.length - 18), '0');
          337     }    
          338 }
          339 /**
          340  *@function 打開所有的子節(jié)點(diǎn) 
          341  */
          342 WebFXTreeAbstractNode.prototype.expandAll = function() {
          343     this.expandChildren();
          344     if ((this.folder) && (!this.open)) {
          345          this.expand();
          346     }
          347 }
          348 /**
          349  *@function 打開本節(jié)點(diǎn)的子節(jié)點(diǎn)。跟 expandAll() 方法合用
          350  */
          351 WebFXTreeAbstractNode.prototype.expandChildren = function() {
          352     for (var i = 0; i < this.childNodes.length; i++) {
          353         this.childNodes[i].expandAll();
          354     } 
          355 }
          356 /**
          357  *@function 關(guān)閉所有的節(jié)點(diǎn)。
          358  */
          359 WebFXTreeAbstractNode.prototype.collapseAll = function() {
          360     this.collapseChildren();
          361     if ((this.folder) && (this.open)) { 
          362          //有值,表示關(guān)閉時(shí),不獲得焦點(diǎn)
          363          this.collapse(true); 
          364     }
          365 }
          366 /**
          367  *@function 關(guān)閉本節(jié)點(diǎn)的子節(jié)點(diǎn),跟 collapseAll()  方法合用。
          368  */
          369 WebFXTreeAbstractNode.prototype.collapseChildren = function() {
          370     for (var i = 0; i < this.childNodes.length; i++) {
          371         this.childNodes[i].collapseAll();
          372     }
          373 }
          374 
          375 
          376 WebFXTreeAbstractNode.prototype.indent = function(lvl, del, last, level, nodesLeft) {
          377     /*
          378      * Since we only want to modify items one level below ourself,
          379      * and since the rightmost indentation position is occupied by
          380      * the plus icon we set this to -2
          381      */
          382     if (lvl == null) { 
          383         lvl = -2
          384     }
          385     var state = 0;
          386     for (var i = this.childNodes.length - 1; i >= 0 ; i--) {
          387         state = this.childNodes[i].indent(lvl + 1, del, last, level);
          388         if (state) { 
          389             return
          390         }
          391     }
          392     if (del) {
          393         if ((level >= this._level) && (document.getElementById(this.id + '-plus'))) {
          394             if (this.folder) {
          395                 document.getElementById(this.id + '-plus').src = (this.open)?webFXTreeConfig.lMinusIcon:webFXTreeConfig.lPlusIcon;
          396                 this.plusIcon = webFXTreeConfig.lPlusIcon;
          397                 this.minusIcon = webFXTreeConfig.lMinusIcon;
          398             }else if (nodesLeft) { 
          399                 document.getElementById(this.id + '-plus').src = webFXTreeConfig.lIcon; 
          400             }
          401             return 1;
          402       }    
          403     }
          404     var foo = document.getElementById(this.id + '-indent-+ lvl);
          405     if (foo) {
          406         if ((foo._last) || ((del) && (last))) { 
          407             foo.src =  webFXTreeConfig.blankIcon; 
          408         } else { 
          409             foo.src =  webFXTreeConfig.iIcon;
          410         }
          411     }
          412     return 0;
          413 }
          414 
          415 
          416 /*
          417  * WebFXTree class
          418  */
          419 
          420 function WebFXTree(sText, sAction, sBehavior, sIcon, sOpenIcon) {
          421     //抽象節(jié)點(diǎn)操作,將 sText ,sAction 添加到樹節(jié)點(diǎn)中
          422     this.base = WebFXTreeAbstractNode;
          423     this.base(sText, sAction);
          424     
          425     //OR 邏輯運(yùn)算符特性,如果 sIcon 字符串不為 空,那么在 Boolean 中表示 true,返回 sIcon,
          426     //如果為空,則返回 webFXTreeConfig.rootIcon 字符串。
          427     this.icon      = sIcon || webFXTreeConfig.rootIcon;
          428     this.openIcon  = sOpenIcon || webFXTreeConfig.openRootIcon;
          429 
          430     /* Defaults to open */
          431     if (webFXTreeConfig.usePersistence) {
          432         this.open  = (webFXTreeHandler.cookies.getCookie(this.id.substr(18,this.id.length - 18)) == '0')?false:true;
          433     } else { 
          434         this.open  = true
          435     }
          436     // 是否折疊
          437     this.folder    = true;
          438     // 是否已經(jīng)瀏覽
          439     this.rendered  = false;
          440     // 是否選擇
          441     this.onSelect  = null;
          442     if (!webFXTreeHandler.behavior) {  
          443          webFXTreeHandler.behavior = sBehavior || webFXTreeConfig.defaultBehavior;
          444     }
          445 }
          446 // 繼承: WebFXTree 繼承 WebFXTreeAbstractNode 所有的方法和屬性。
          447 WebFXTree.prototype = new WebFXTreeAbstractNode;
          448 
          449 WebFXTree.prototype.setBehavior = function (sBehavior) {
          450     webFXTreeHandler.behavior =  sBehavior;
          451 };
          452 
          453 WebFXTree.prototype.getBehavior = function (sBehavior) {
          454     return webFXTreeHandler.behavior;
          455 };
          456 
          457 /**
          458  *@function 樹得到焦點(diǎn)時(shí),返回得到焦點(diǎn)的節(jié)點(diǎn)信息
          459  */
          460 WebFXTree.prototype.getSelected = function() {
          461     if (webFXTreeHandler.selected) { 
          462         return webFXTreeHandler.selected; 
          463     }
          464     else { 
          465         return null;
          466     }
          467 }
          468 /**
          469  * @function 根節(jié)點(diǎn) remove 方法為空,不能刪除根節(jié)點(diǎn)吧。
          470  */
          471 WebFXTree.prototype.remove = function() { }
          472 
          473 /**
          474  * @function 擴(kuò)張方法,即打開根節(jié)點(diǎn)下的葉節(jié)點(diǎn)。
          475  */
          476 WebFXTree.prototype.expand = function() {
          477     this.doExpand();
          478 }
          479 /**
          480  *@function 收縮方法,即關(guān)閉根節(jié)點(diǎn)下的所有葉節(jié)點(diǎn)。
          481  *對(duì)象得到焦點(diǎn)
          482  */
          483 WebFXTree.prototype.collapse = function(b) {
          484     if (!b) { 
          485         this.focus(); 
          486     }
          487     this.doCollapse();
          488 }
          489 /*
          490 WebFXTree.prototype.getFirst = function() {
          491     return null;
          492 }
          493 
          494 WebFXTree.prototype.getLast = function() {
          495     return null;
          496 }
          497 
          498 WebFXTree.prototype.getNextSibling = function() {
          499     return null;
          500 }
          501 
          502 WebFXTree.prototype.getPreviousSibling = function() {
          503     return null;
          504 }
          505 */
          506 WebFXTree.prototype.keydown = function(key) {
          507     if (key == 39) {
          508         if (!this.open) { this.expand(); }
          509         else if (this.childNodes.length) { this.childNodes[0].select(); }
          510         return false;
          511     }
          512     if (key == 37) { this.collapse(); return false; }
          513     if ((key == 40&& (this.open) && (this.childNodes.length)) { this.childNodes[0].select(); return false; }
          514     return true;
          515 }
          516 
          517 WebFXTree.prototype.toString = function() {
          518     var str = "<div id=\"" + this.id + "\" ondblclick=\"webFXTreeHandler.toggle(this);\" class=\"webfx-tree-item\" onkeydown=\"return webFXTreeHandler.keydown(this, event)\">" +
          519         "<img id=\"" + this.id + "-icon\" class=\"webfx-tree-icon\" src=\"" + ((webFXTreeHandler.behavior == 'classic' && this.open)?this.openIcon:this.icon) + "\" onclick=\"webFXTreeHandler.select(this);\">" +
          520         "<a href=\"" + this.action + "\" id=\"" + this.id + "-anchor\" onfocus=\"webFXTreeHandler.focus(this);\" onblur=\"webFXTreeHandler.blur(this);\"" +
          521         (this.target ? " target=\"" + this.target + "\"" : ""+
          522         ">" + this.text + "</a></div>" +
          523         "<div id=\"" + this.id + "-cont\" class=\"webfx-tree-container\" style=\"display: " + ((this.open)?'block':'none') + ";\">";
          524     var sb = [];
          525     for (var i = 0; i < this.childNodes.length; i++) {
          526         sb[i] = this.childNodes[i].toString(i, this.childNodes.length);
          527     }
          528     this.rendered = true;
          529     // 返回字符串值,其中包含了連接到一起的數(shù)組的所有元素,元素由指定分隔符分隔開來.
          530     return str + sb.join(""+ "</div>";
          531 };
          532 
          533 /*
          534  * WebFXTreeItem class
          535  */
          536 
          537 function WebFXTreeItem(sText, sAction, eParent, sIcon, sOpenIcon) {
          538     this.base = WebFXTreeAbstractNode;
          539     this.base(sText, sAction);
          540     /* Defaults to close */
          541     if (webFXTreeConfig.usePersistence) {
          542         this.open = (webFXTreeHandler.cookies.getCookie(this.id.substr(18,this.id.length - 18)) == '1')?true:false;
          543     } else { 
          544         this.open = false
          545     }
          546     if (sIcon) { 
          547         this.icon = sIcon;
          548     }
          549     if (sOpenIcon) { 
          550         this.openIcon = sOpenIcon; 
          551     }
          552     if (eParent) { 
          553          eParent.add(this); 
          554     }
          555 }
          556 
          557 // WebFXTreeItem 類繼承  WebFXTreeAbstractNode 抽象類所有的屬性和方法。
          558 WebFXTreeItem.prototype = new WebFXTreeAbstractNode;
          559 
          560 /**
          561  *@function WebFXTreeItem 節(jié)點(diǎn)刪除方法
          562  */
          563 WebFXTreeItem.prototype.remove = function() {
          564     var iconSrc = document.getElementById(this.id + '-plus').src;
          565     // 父節(jié)點(diǎn)
          566     var parentNode = this.parentNode;
          567     // 上一個(gè)兄弟節(jié)點(diǎn)
          568     var prevSibling = this.getPreviousSibling(true);
          569     // 下一個(gè)兄弟節(jié)點(diǎn)
          570     var nextSibling = this.getNextSibling(true);
          571     // 父節(jié)點(diǎn)的折疊屬性
          572     var folder = this.parentNode.folder;
          573     // 判斷本節(jié)點(diǎn)是不是父節(jié)點(diǎn)的最后一個(gè)子節(jié)點(diǎn)。
          574     var last = ((nextSibling) && (nextSibling.parentNode) && (nextSibling.parentNode.id == parentNode.id))?false:true;
          575     // 本節(jié)點(diǎn)的上一個(gè)兄弟節(jié)點(diǎn)得到焦點(diǎn)。
          576     this.getPreviousSibling().focus();
          577     
          578     this._remove();
          579     
          580     if (parentNode.childNodes.length == 0) {
          581         document.getElementById(parentNode.id + '-cont').style.display = 'none';
          582         parentNode.doCollapse();
          583         parentNode.folder = false;
          584         parentNode.open = false;
          585     }
          586     if (!nextSibling || last) { parentNode.indent(nulltrue, last, this._level, parentNode.childNodes.length); }
          587     if ((prevSibling == parentNode) && !(parentNode.childNodes.length)) {
          588         prevSibling.folder = false;
          589         prevSibling.open = false;
          590         iconSrc = document.getElementById(prevSibling.id + '-plus').src;
          591         iconSrc = iconSrc.replace('minus', '').replace('plus', '');
          592         document.getElementById(prevSibling.id + '-plus').src = iconSrc;
          593         document.getElementById(prevSibling.id + '-icon').src = webFXTreeConfig.fileIcon;
          594     }
          595     if (document.getElementById(prevSibling.id + '-plus')) {
          596         if (parentNode == prevSibling.parentNode) {
          597             iconSrc = iconSrc.replace('minus', '').replace('plus', '');
          598             document.getElementById(prevSibling.id + '-plus').src = iconSrc;
          599 }    }    }
          600 
          601 /**
          602  *@function 刪除方法的據(jù)體操作
          603  */
          604 WebFXTreeItem.prototype._remove = function() {
          605      //遞歸刪除節(jié)點(diǎn)下的所有子節(jié)點(diǎn)
          606     for (var i = this.childNodes.length - 1; i >= 0; i--) {
          607         this.childNodes[i]._remove();
          608      }
          609      /*
          610      * 循環(huán)查詢所有的子節(jié)點(diǎn),找到本節(jié)點(diǎn)在子節(jié)點(diǎn)的位置,將本節(jié)點(diǎn)后的節(jié)點(diǎn)分別向前占位,并使父節(jié)點(diǎn)的節(jié)點(diǎn)總量減一。
          611      * 如果節(jié)點(diǎn)的位置 +1 等于父節(jié)點(diǎn)的子節(jié)點(diǎn)總數(shù),那么設(shè)置父節(jié)點(diǎn)的_last 為 true,即最后一個(gè)節(jié)點(diǎn)。
          612      */
          613     for (var i = 0; i < this.parentNode.childNodes.length; i++) {
          614         if (this == this.parentNode.childNodes[i]) {
          615             for (var j = i; j < this.parentNode.childNodes.length; j++) {
          616                 this.parentNode.childNodes[j] = this.parentNode.childNodes[j+1];
          617             }
          618             this.parentNode.childNodes.length -= 1;
          619             if (i + 1 == this.parentNode.childNodes.length) { 
          620                  this.parentNode._last = true
          621             }
          622             break;
          623       }    
          624     }
          625     //本ID節(jié)點(diǎn)為NULL
          626     webFXTreeHandler.all[this.id] = null;
          627     //得到本節(jié)點(diǎn)元素,如果存在讓父元素刪除,
          628     var tmp = document.getElementById(this.id);
          629     if (tmp) { 
          630         tmp.parentNode.removeChild(tmp); 
          631     }
          632     //得到本節(jié)點(diǎn)元素的 子空間,如果存在,刪除。
          633     tmp = document.getElementById(this.id + '-cont');
          634     if (tmp) { 
          635         tmp.parentNode.removeChild(tmp); 
          636     }
          637 }
          638 
          639 /**
          640  *@function  擴(kuò)張方法
          641  */
          642 WebFXTreeItem.prototype.expand = function() {
          643     this.doExpand();
          644     document.getElementById(this.id + '-plus').src = this.minusIcon;
          645 }
          646 /**
          647  *@function   收縮方法 
          648  */
          649 WebFXTreeItem.prototype.collapse = function(b) {
          650     if (!b) { this.focus(); }
          651     this.doCollapse();
          652     document.getElementById(this.id + '-plus').src = this.plusIcon;
          653 }
          654 /**
          655  *@function 返回第一個(gè)節(jié)點(diǎn)
          656  */
          657 WebFXTreeItem.prototype.getFirst = function() {
          658     return this.childNodes[0];
          659 }
          660 
          661 /*
          662  *@function 返回上一個(gè)最后的子節(jié)點(diǎn)
          663  */
          664 WebFXTreeItem.prototype.getLast = function() {
          665     //如果節(jié)點(diǎn)是打開,那么遞歸得到最后一個(gè)節(jié)點(diǎn);否則返回這個(gè)節(jié)點(diǎn)。
          666     if (this.childNodes[this.childNodes.length - 1].open) { 
          667          return this.childNodes[this.childNodes.length - 1].getLast(); 
          668     }else { 
          669         return this.childNodes[this.childNodes.length - 1]; 
          670     }
          671 }
          672 /**
          673  *@function 獲得本節(jié)點(diǎn)的下一個(gè)子節(jié)點(diǎn)。
          674  */
          675 WebFXTreeItem.prototype.getNextSibling = function() {
          676     for (var i = 0; i < this.parentNode.childNodes.length; i++) {
          677         if (this == this.parentNode.childNodes[i]) { break; }
          678     }
          679     if (++== this.parentNode.childNodes.length) { return this.parentNode.getNextSibling(); }
          680     else { return this.parentNode.childNodes[i]; }
          681 }
          682 
          683 /**
          684  *@function 獲得本節(jié)點(diǎn)的前一個(gè)兄弟節(jié)點(diǎn)
          685  */
          686 WebFXTreeItem.prototype.getPreviousSibling = function(b) {
          687     //判斷兄弟節(jié)點(diǎn)中,本節(jié)點(diǎn)所占的下標(biāo)。
          688     for (var i = 0; i < this.parentNode.childNodes.length; i++) {
          689         if (this == this.parentNode.childNodes[i]) { 
          690             break
          691         }
          692     }
          693     //如果下標(biāo) i  為零,即父節(jié)點(diǎn)只有一個(gè)子節(jié)點(diǎn),反回父節(jié)點(diǎn)。 
          694     if (i == 0) { 
          695         return this.parentNode; 
          696     } else {
          697         if ((this.parentNode.childNodes[--i].open) || (b && this.parentNode.childNodes[i].folder)) { 
          698              return this.parentNode.childNodes[i].getLast(); 
          699         }    else { 
          700             return this.parentNode.childNodes[i];
          701       }
          702     } 
          703 }
          704 
          705 WebFXTreeItem.prototype.keydown = function(key) {
          706     if ((key == 39&& (this.folder)) {
          707         if (!this.open) { this.expand(); }
          708         else { this.getFirst().select(); }
          709         return false;
          710     }
          711     else if (key == 37) {
          712         if (this.open) { this.collapse(); }
          713         else { this.parentNode.select(); }
          714         return false;
          715     }
          716     else if (key == 40) {
          717         if (this.open) { this.getFirst().select(); }
          718         else {
          719             var sib = this.getNextSibling();
          720             if (sib) { sib.select(); }
          721         }
          722         return false;
          723     }
          724     else if (key == 38) { this.getPreviousSibling().select(); return false; }
          725     return true;
          726 }
          727 /**
          728  *@function 返回該對(duì)象的字符串表達(dá)
          729  */
          730 WebFXTreeItem.prototype.toString = function (nItem, nItemCount) {
          731     var foo = this.parentNode;
          732     var indent = '';
          733     if (nItem + 1 == nItemCount) { this.parentNode._last = true; }
          734     var i = 0;
          735     while (foo.parentNode) {
          736         foo = foo.parentNode;
          737         indent = "<img id=\"" + this.id + "-indent-" + i + "\" src=\"" + ((foo._last)?webFXTreeConfig.blankIcon:webFXTreeConfig.iIcon) + "\">" + indent;
          738         i++;
          739     }
          740     this._level = i;
          741     if (this.childNodes.length) { this.folder = 1; }
          742     else { this.open = false; }
          743     if ((this.folder) || (webFXTreeHandler.behavior != 'classic')) {
          744         if (!this.icon) { this.icon = webFXTreeConfig.folderIcon; }
          745         if (!this.openIcon) { this.openIcon = webFXTreeConfig.openFolderIcon; }
          746     }
          747     else if (!this.icon) { this.icon = webFXTreeConfig.fileIcon; }
          748     var label = this.text.replace(/</g, '&lt;').replace(/>/g, '&gt;');
          749     var str = "<div id=\"" + this.id + "\" ondblclick=\"webFXTreeHandler.toggle(this);\" class=\"webfx-tree-item\" onkeydown=\"return webFXTreeHandler.keydown(this, event)\">" +
          750         indent +
          751         "<img id=\"" + this.id + "-plus\" src=\"" + ((this.folder)?((this.open)?((this.parentNode._last)?webFXTreeConfig.lMinusIcon:webFXTreeConfig.tMinusIcon):((this.parentNode._last)?webFXTreeConfig.lPlusIcon:webFXTreeConfig.tPlusIcon)):((this.parentNode._last)?webFXTreeConfig.lIcon:webFXTreeConfig.tIcon)) + "\" onclick=\"webFXTreeHandler.toggle(this);\">" +
          752         "<img id=\"" + this.id + "-icon\" class=\"webfx-tree-icon\" src=\"" + ((webFXTreeHandler.behavior == 'classic' && this.open)?this.openIcon:this.icon) + "\" onclick=\"webFXTreeHandler.select(this);\">" +
          753         "<a href=\"" + this.action + "\" id=\"" + this.id + "-anchor\" onfocus=\"webFXTreeHandler.focus(this);\" onblur=\"webFXTreeHandler.blur(this);\"" +
          754         (this.target ? " target=\"" + this.target + "\"" : ""+
          755         ">" + label + "</a></div>" +
          756         "<div id=\"" + this.id + "-cont\" class=\"webfx-tree-container\" style=\"display: " + ((this.open)?'block':'none') + ";\">";
          757     var sb = [];
          758     for (var i = 0; i < this.childNodes.length; i++) {
          759         sb[i] = this.childNodes[i].toString(i,this.childNodes.length);
          760     }
          761     this.plusIcon = ((this.parentNode._last)?webFXTreeConfig.lPlusIcon:webFXTreeConfig.tPlusIcon);
          762     this.minusIcon = ((this.parentNode._last)?webFXTreeConfig.lMinusIcon:webFXTreeConfig.tMinusIcon);
          763     return str + sb.join(""+ "</div>";
          764 }
          765 
          766 
          767         面向?qū)ο蟮乃枷雭砭帉?nbsp;javascript  語言,運(yùn)用很多讓人容易忽略的js語言知識(shí),有著 DOM 方式,使整個(gè)框架看起來讓人驚嘆。
          768 框架原來如此簡單!
          769 
          下載框架

          posted on 2009-07-09 09:44 星期五 閱讀(1219) 評(píng)論(0)  編輯  收藏 所屬分類: WEB FX

          主站蜘蛛池模板: 永和县| 富宁县| 贵阳市| 慈溪市| 盐亭县| 洞头县| 建水县| 淮安市| 乌什县| 清远市| 东宁县| 中山市| 修文县| 延长县| 宁河县| 湖口县| 陆川县| 旅游| 台南县| 原平市| 彭阳县| 玉龙| 泸州市| 黔东| 布拖县| 定南县| 宁陕县| 锡林郭勒盟| 军事| 玉溪市| 德保县| 延长县| 商都县| 甘肃省| 广饶县| 通河县| 栖霞市| 正阳县| 鞍山市| 上杭县| 上高县|