背景
在jsp頁面錄入時,有這么一個字段“籍貫”,該字段可以用編碼表示,以便日后作統計分析操作,但這需對全國地區進行編碼,共計4千條左右。為了方便用戶選擇,原本我使用的是struts + dtree實現的國家樹,這樣的問題是:需和后臺數據庫交互,頁面需要刷新,實時性較差。考慮全國地區編碼相對比較穩定,所以我打算完全使用javascript實現。
要求
1、 根據當前用戶所在地區編碼生成默認的樹。
2、 將被點擊節點信息返回給父窗口。
思路
如果將全國地區樹一次性構建完畢,由于包含的內容太多,會引起瀏覽器崩潰,所以思路是只加載用戶需要加載的部分,也就是用戶點擊父節點時就加載其子節點。
問題
1、 全國地區信息的js保存。
2、 如何結合dtree的事件操作。
3、 與父窗口的交互。
解決
1、 全國地區信息的js保存
我使用js自定義對象,保存全國地區信息,定義兩個對象:Region和Country,Region是地區對象,Country是國家對象,包含若干Region對象。
// Region object function Region(id, pid, name, level) {
this.id = id; //節點id this.pid = pid; //父節點id this.name = name; //節點name
this.level = level; //節點級別
}; // Country object function Country(objName) {
this.name = objName; //國家名稱
this.regions = []; //地區容器
this.init(); //初始化地區
}; // Init country Country.prototype.init = function() { this.regions[this.regions.length] = new Region('00011010100000','00011000000000','東城區','C'); this.regions[this.regions.length] = new Region('00011010200000','00011000000000','西城區','C'); this.regions[this.regions.length] = new Region('00011010300000','00011000000000','崇文區','C'); } |
2、 如何結合dtree的事件操作
dtree的原理是:用戶初始化dtree對象的aNodes數組,數組中存放的是Node對象,然后調用dtree的tostring()方法生成樹狀html語法,主要是div和圖片鏈接。
dtree有一個s的方法,就是高亮顯示選中節點的方法,加入如下語法:
// Highlights the selected node dTree.prototype.s = function(id) { if (!this.config.useSelection) return; var cn = this.aNodes[id];
//--在該處添加以下語句,目的是在用戶點擊 //--node時向opener添加該node相關信息 this.allName = cn.name; this.allId = cn.id; this.parentNodePath(cn.pid);
//執行用戶語法 eval(window.dialogArguments.imaginaryOperate);
if(cn.level == 'C' || cn.level == 'c'){ self.close(); }
//============================================= //1、將dtree的節點對象保存到數組對象 regions = []; for(i = 0;i < d.aNodes.length;i ++){ regions[regions.length] = new Region(d.aNodes[i].id,d.aNodes[i].pid,d.aNodes[i].name,d.aNodes[i].level); }
//2、銷毀dtree的節點對象 d.aNodes = [];
//3、獲得點擊節點的子節點 sRegions = country.getSonRegionsByPid(cn.id);
//4、將子節點加入到regions中,注意已有就不應再加入 for(i = 0;i < sRegions.length;i ++){ flag = true; for(j = 0;j < regions.length;j ++){ if(sRegions[i].id == regions[j].id){ flag = false; break; } } if(flag) regions[regions.length] = sRegions[i]; }
//5、重新構造dtree for(i = 0;i<regions.length;i++){ d.add(regions[i].id,regions[i].pid,regions[i].name,regions[i].level); }
document.getElementById('dtree').innerHTML = d.toString();
//6、打開被點擊的點 d.openTo(cn.id); //=============================================
/* if (cn._hc && !this.config.folderLinks) return; if (this.selectedNode != id) { if (this.selectedNode || this.selectedNode==0) { eOld = document.getElementById("s" + this.obj + this.selectedNode); eOld.className = "node"; } eNew = document.getElementById("s" + this.obj + id); eNew.className = "nodeSel"; this.selectedNode = id; if (this.config.useCookies) this.setCookie('cs' + this.obj, cn.id); } */ }; |
3、 與父窗口的交互
<script language="javascript"> <!-- //用以存放初始節點id和operate的虛變量,也作為window的變量 var imaginaryId; var imaginaryOperate; /* showTreeDialog 功能:打開國家樹窗口 參數:aId 父節點id aOperate 節點返回數據的操作 //---詳細例程---// //opener.countPerYearConditionForm.regDepartment.value=cn.id //“=”之前指父窗口對象 //“=”之后指可返回的值:cn.id 對應id // cn.pid 對應father_id // cn.name 對應name //增加兩個參數:最終子節點到根節點的路由的name和id串 //串接規則:小單位在前大單位在后,之間用"##"隔開 // this.allName // this.allId //可以將多個操作寫入,之間以分號“;”隔開,例如: //window.dialogArguments.regionname.value=this.allName;window.dialogArguments.regionid.value=cn.id; aWidth 窗口的寬度 aHeight 窗口的高度 */ function showTreeDialog(aId,aOperate,aWidth,aHeight) { imaginaryId = aId; imaginaryOperate = aOperate;
_feature="status:no;help:no;dialogHeight:"+aHeight+"px;dialogWidth:"+aWidth+"px";
window.showModalDialog('country.html',window,_feature) } --> </script> |
注意:其中多定義了兩個用以存放初始節點id和operate的虛變量,傳遞參數是將window傳過去,這樣就實現了主父窗口交互。
附件:國家樹源碼