윈폼 측면에서는 트리 메뉴가 매우 유용하고 이를 구현하는 것도 매우 편리해서 페이지에 트리 메뉴를 넣어볼까 생각하게 되었습니다. 저는 dtree라는 도구를 선택했습니다. 인터넷에서 페이지 트리 메뉴를 구현하는 방법은 여러 가지가 있지만 이 방법이 더 사용하기 쉽고, 구성도 비교적 간단하고 사용이 빠른 것 같습니다. dtree는 순수 js이므로 jar 패키지를 가져올 필요가 없으며 구성은 js에서만 구성하면 됩니다. 그리고 이제는 인터넷 전문가에 의해 수정된 개선된 버전이 많이 있으며, 확인란이 추가되어 더욱 편리해졌습니다. 개발 과정에서 가장 어려운 점은 데이터의 상호작용입니다.dtree는 순수 js이기 때문에 백그라운드와 상호작용할 방법이 없습니다.제 방법은 먼저 백그라운드 상호작용을 통해 데이터를 페이지에 전달한 다음 이를 전달하는 것입니다. js 내부로. 백그라운드에서 페이지에 전달된 데이터를 문자열로 연결한 다음 js로 잘라 데이터를 배열로 통합합니다.
백그라운드 데이터 처리 코드:
// Node object
function Node(id, pid, name, checked, value, icon ,url, title, target, iconOpen, open) {
this.id = id;
this.pid = pid;
this.name = name;
//是否在该节点添加复选框并设置选中状态,true:选中,false:不选中,null:不添加
this.checked = checked==null?null:(checked || false);
this.value = value;//增加value属性,选中复选框,输入框内得到的就是这个value值
this.url = url;
this.title = title;
this.target = target;
this.icon = icon;
this.iconOpen = iconOpen;
this._io = open || false;
this._is = false;
this._ls = false;
this._hc = false;
this._ai = 0;
this._p;
};
// Tree object
function dTree(objName, path) {
//路径
this.path = path ||'';
//加载css文件
this.loadCssFile(this.path+'dtree.css');
this.config = {
target : null,
folderLinks : true,
useSelection : true,
useCookies : true,
useLines : true,
useIcons : true,
useStatusText : false,
closeSameLevel : false,
inOrder : false,
//是否显示复选框,true显示,false不显示
checkbox:false,
objValueId:''
}
this.icon = {
root : this.path + 'images/img/base.gif',
folder : this.path + 'images/img/folder.gif',
folderOpen : this.path + 'images/img/folderopen.gif',
node : this.path + 'images/img/page.gif',
empty : this.path + 'images/img/empty.gif',
line : this.path + 'images/img/line.gif',
join : this.path + 'images/img/join.gif',
joinBottom : this.path + 'images/img/joinbottom.gif',
plus : this.path + 'images/img/plus.gif',
plusBottom : this.path + 'images/img/plusbottom.gif',
minus : this.path + 'images/img/minus.gif',
minusBottom : this.path + 'images/img/minusbottom.gif',
nlPlus : this.path + 'images/img/nolines_plus.gif',
nlMinus : this.path + 'images/img/nolines_minus.gif'
};
this.obj = objName;
this.aNodes = [];
this.aIndent = [];
this.root = new Node(-1);
this.selectedNode = null;
this.selectedFound = false;
this.completed = false;
};
//设置选中节点
dTree.prototype.checkedNodes=function(){
if(this.config.objValueId==''){
return;
}
var val=document.getElementById(this.config.objValueId).value;
if(val==''){
return;
}
val=val.split(',');
var o=null;
for(var i=0;i
o=document.getElementById('cbx_'+this.obj+val[i]);
if(o){
o.checked=true;
}
}
};
//实现输入框内自动输入选中项的value值
dTree.prototype.update=function(){
if(this.config.objValueId==''){
return;
}
var cbx=null,v=[];
// v.push(aa);
var ns=this.aNodes;
for(var i=0;icbx=document.getElementById('cbx_'+this.obj+ns[i].id);
if(cbx){
if(cbx.checked){
if(ns[i].pid!='0'){
v.push(cbx.value);//原先是得到节点的id的,换成value,可以实现选中联系人,得到号码。
}
}
}
}
document.getElementById(this.config.objValueId).value=v.join();
};
//加载css文件
dTree.prototype.loadCssFile=function (file) {
try{
var head=document.getElementsByTagName("head")[0];
var links=head.getElementsByTagName('link');
var i=0;
for(var i=0;iif(links[i].getAttribute('href').toLowerCase().indexOf(file.toLowerCase())>-1){
return;
}
}
var f = document.createElement("link");
f.setAttribute("rel", "stylesheet");
f.setAttribute("type", "text/css");
f.setAttribute("href", file);
head.appendChild(f);
}catch(ex){
alert('加载css文件出错:'+ex.message);
}
};
// Adds a new node to the node array
dTree.prototype.add = function(id, pid, name, checked, value,icon,url, title, target,iconOpen, open) {
this.aNodes[this.aNodes.length] = new Node(id, pid, name, checked, value,icon,url, title, target, iconOpen, open);
};
// Open/close all nodes
dTree.prototype.openAll = function() {
this.oAll(true);
};
dTree.prototype.closeAll = function() {
this.oAll(false);
};
// Outputs the tree to the page
dTree.prototype.toString = function() {
var str = '\n';
if (document.getElementById) {
if (this.config.useCookies) this.selectedNode = this.getSelected();
str += this.addNode(this.root);
} else str += 'Browser not supported.';
str += '
';
if (!this.selectedFound) this.selectedNode = null;
this.completed = true;
return str;
};
// Creates the tree structure
dTree.prototype.addNode = function(pNode) {
var str = '';
var n=0;
if (this.config.inOrder) n = pNode._ai;
for (n; nif (this.aNodes[n].pid == pNode.id) {
var cn = this.aNodes[n];
cn._p = pNode;
cn._ai = n;
this.setCS(cn);
if (!cn.target && this.config.target) cn.target = this.config.target;
if (cn._hc && !cn._io && this.config.useCookies) cn._io = this.isOpen(cn.id);
if (!this.config.folderLinks && cn._hc) cn.url = null;
if (this.config.useSelection && cn.id == this.selectedNode && !this.selectedFound) {
cn._is = true;
this.selectedNode = n;
this.selectedFound = true;
}
str += this.node(cn, n);
if (cn._ls) break;
}
}
return str;
};
// Creates the node icon, url and text
dTree.prototype.node = function(node, nodeId) {
var str = '';
if (node._hc) {
str += '';
str += this.addNode(node);
str += '
';
}
this.aIndent.pop();
str을 반환합니다;
};
// 빈 아이콘과 선 아이콘 추가
dTree.prototype.indent = function(node, nodeId) {
var str = '';
if (this.root.id != node.pid) {
for (var n=0; nstr = '
';
(node._ls) ? this.aIndent.push(0) : this.aIndent.push(1);
if (node._hc) {
str = '
';
} else str = '
';
}
return str;
};
// 노드에 자식이 있는지, 마지막 형제인지 확인
dTree.prototype.setCS = function(node) {
var lastId;
for (var n=0; nif (this.aNodes[n].pid == node.id) node._hc = true;
if (this.aNodes[n].pid == node.pid) lastId = this.aNodes[n].id;
}
if (lastId==node.id) node._ls = true;
};
// 선택한 노드를 반환합니다.
dTree.prototype.getSelected = function() {
var sn = this.getCookie('cs' this.obj);
반품(sn) ? sn : null;
};
// 선택한 노드를 강조 표시합니다.
dTree.prototype.s = function(id) {
if (!this.config.useSelection) return;
var cn = this.aNodes[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 = "노드";
}
eNew = document.getElementById("s" this.obj id);
eNew.className = "nodeSel";
this.selectedNode = id;
if (this.config.useCookies) this.setCookie('cs' this.obj, cn.id);
}
};
// 열기 또는 닫기 전환
dTree.prototype.o = function(id) {
var cn = this.aNodes[id];
this.nodeStatus(!cn._io, id, cn._ls);
cn._io = !cn._io;
if (this.config.closeSameLevel) this.closeLevel(cn);
if (this.config.useCookies) this.updateCookie();
//更新选中值if(this.config.objValueId!='')
this.update();
};
// 모든 노드 열기 또는 닫기
dTree.prototype.oAll = function(status) {
for (var n=0; nif ( this.aNodes[n]._hc && this.aNodes[n].pid != this.root.id) {
this.nodeStatus(status, n, this.aNodes[n]._ls)
this .aNodes[n]._io = 상태;
}
}
if (this.config.useCookies) this.updateCookie();
};
// 특정 노드에 대한 트리 열기
dTree.prototype.openTo = function(nId, bSelect, bFirst) {
if (!bFirst) {
for (var n=0; n< ;this.aNodes.length; n ) {
if (this.aNodes[n].id == nId) {
nId=n;
휴식;
}
}
}
var cn=this.aNodes[nId];
if (cn.pid==this.root.id || !cn._p) return;
cn._io = 참;
cn._is = b선택;
if (this.completed && cn._hc) this.nodeStatus(true, cn._ai, cn._ls);
if (this.completed && bSelect) this.s(cn._ai);
else if (bSelect) this._sn=cn._ai;
this.openTo(cn._p._ai, false, true);
};
// 특정 노드와 동일한 수준의 모든 노드를 닫습니다.
dTree.prototype.closeLevel = function(node) {
for (var n=0; nif (this.aNodes[n].pid == node.pid && this.aNodes[n].id != node.id && this.aNodes[n]._hc) {
this.nodeStatus( false, n, this.aNodes[n]._ls);
this.aNodes[n]._io = false;
this.closeAllChildren(this.aNodes[n]);
}
}
}
// 노드의 모든 하위 항목을 닫습니다.
dTree.prototype.closeAllChildren = function(node) {
for (var n=0; nif (this.aNodes[n].pid == node.id && this.aNodes[n]._hc) {
if (this.aNodes[n]._io ) this.nodeStatus(false, n, this.aNodes[n]._ls);
this.aNodes[n]._io = false;
this.closeAllChildren(this.aNodes[n]);
}
}
}
// 노드 상태 변경(열림 또는 닫힘)
dTree.prototype.nodeStatus = function(status, id, Bottom) {
try {
eDiv = document.getElementById('d' this.obj id);
eJoin = document.getElementById('j' this.obj id);
//****选择
if(this.config.checkbox){
cbx = document.getElementById('cbx_' this.obj id);
cbx.checked=상태;
cbxChild= eDiv.getElementsByTagName('input');
for(var i=0 ;icbxChild[i].checked=status;
}
}
//****选择
if (this.config.useIcons) {
eIcon = document.getElementById('i' this.obj id);
eIcon.src = (상태) ? this.aNodes[id].iconOpen : this.aNodes[id].icon;
}
eJoin.src = (this.config.useLines)?
((상태)?((하단)?this.icon.minusBottom:this.icon.minus):((하단)?this.icon.plusBottom:this.icon.plus)):
(( 상태)?this.icon.nlMinus:this.icon.nlPlus);
eDiv.style.display = (상태) ? '차단': '없음';
}catch(ex){
}
};
// [쿠키] 쿠키 삭제
dTree.prototype.clearCookie = function() {
var now = new Date();
var 어제 = new Date(now.getTime() - 1000 * 60 * 60 * 24);
this.setCookie('co' this.obj, 'cookieValue', 어제);
this.setCookie('cs' this.obj, 'cookieValue', 어제);
};
// [Cookie] 쿠키에 값 설정
dTree.prototype.setCookie = function(cookieName, cookieValue,expires, path, domain, secure) {
document.cookie =
escape(cookieName ) '=' escape(cookieValue)
(expires ? ';expires='expires.toGMTString() : '')
(경로 ? '; path=' 경로 : '')
(도메인 ? '; 도메인=' 도메인 : '')
(보안 ? '; 보안' : '');
};
// [Cookie] 쿠키에서 값을 가져옵니다.
dTree.prototype.getCookie = function(cookieName) {
var cookieValue = '';
var posName = document.cookie.indexOf(escape(cookieName) '=');
if (posName != -1) {
var posValue = posName (escape(cookieName) '=').length;
var endPos = document.cookie.indexOf(';', posValue);
if (endPos != -1) cookieValue = unescape(document.cookie.substring(posValue, endPos));
else cookieValue = unescape(document.cookie.substring(posValue));
}
return(cookieValue);
};
// [쿠키] 열린 노드의 ID를 문자열로 반환합니다.
dTree.prototype.updateCookie = function() {
var str = '';
for (var n=0; nif (this.aNodes[n]._io && this.aNodes[n].pid != this.root.id ) {
if (str) str = '.';
str = this.aNodes[n].value;
}
}
this.setCookie('co' this.obj, str);
};
// [쿠키] 쿠키에 노드 ID가 있는지 확인
dTree.prototype.isOpen = function(id) {
var aOpen = this.getCookie('co' this.obj).split ('.');
for (var n=0; nif (aOpen[n] == id) return true;
거짓을 반환합니다.
};
// 브라우저에서 Push 및 Pop이 구현되지 않은 경우
if (!Array.prototype.push) {
Array.prototype.push = function array_push() {
for(var i= 0;ithis[this.length]=arguments[i];
return this.length;
}
};
if (!Array.prototype.pop) {
Array.prototype.pop = function array_pop() {
lastElement = this[this.length-1];
this.length = Math.max(this.length-1,0);
마지막 요소를 반환합니다.
}
};