⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 tree.js

📁 网页上经常会用到的树状结构源代码,模拟文件夹方式,采用ajax方式动态加载数据,避免一次性加载带来的数据量过大的效率问题.
💻 JS
字号:
RayeTreeImg ={
	fd: "tree/folder.gif",
	of: "tree/openfolder.gif",
	i: "tree/I.png",
	l: "tree/L.png",
	t: "tree/T.png",
	lm: "tree/Lminus.png",
	lp: "tree/Lplus.png",
	tm: "tree/Tminus.png",
	tp: "tree/Tplus.png",
	s: "tree/blank.png",
	system:function(idx){
		return eval("imagePath + " + "this." + idx);
	}
	,
	custom:function(img){
		return imagePath + img;
	}
}
function RayeTree(e, loadMethod){
	this.type = "tree";
	this.element = e;
	this.all = Array();
	this.exp = Array();
	this.element.instance = this;
	this.childNodes = new RayeItemCollection();
	e.onmousedown = RayeTree.eventHandlers.onmousedown;
	e.ondblclick = RayeTree.eventHandlers.ondblclick;
	e.oncontextmenu = RayeTree.eventHandlers.oncontextmenu;
	this.loadMethod = loadMethod;
	this.eventListener ={
		onselectchange:null,
		ondblclick:null,
		ondragstart:null,
		oncontextmenu:null
	};
	var oThis = this;
	this.readyState = 1;
}
RayeTree.prototype.addEventListener = function(s,cb){
	var retval = false;
	switch(s){
		case "onselectchange":
		this.eventListener.onselectchange = cb;
		break;
		case "ondblclick":
		this.eventListener.ondblclick = cb;
		break;
		case "ondragstart":
		this.eventListener.ondragstart = cb;
		break;
		case "oncontextmenu":
		this.eventListener.oncontextmenu = cb;
		default:break;
	}
	return true;
}
RayeTree.prototype.dragObject = function(){
	var so = this.childNodes.item(this.childNodes.selectedIndex[0]);
	var e = document.createElement("nobr");
	e.className = "treeItem";
	var icn = so.ue.icon.cloneNode(true);
	var lbl = so.ue.label.cloneNode(true);
	e.appendChild(icn);
	e.appendChild(lbl);
	icn = lbl = null;
	return Array({
		item:so, element:e, posElement:so.ue.icon
	}
	);
}
RayeTree.prototype.getDropItem = function(){
	return this.childNodes.item(this.childNodes.selectedIndex[0]);
}
RayeTree.prototype.ondrag = function(pos, oso){
	var c = this.childNodes;
	var l = this.childNodes.length;
	var to = c.item(2).element
	var tp = getOffset(to);
	var offset ={
		x:tp.left - to.offsetLeft, y:tp.top - to.offsetTop
	};
	var so = null;
	for(var i = 0;i < l;i ++){
		ty = c.item(i).element.offsetTop + offset.y - this.element.scrollTop;
		if(ty <= pos.y && ty + c.item(i).ue.icon.offsetHeight >= pos.y){
			so = c.item(i);
			break;
		}
	}
	if(null != so){
		if(!RayeTree.contains(oso.element, so.element)){
			this.childNodes.select(so.index);
		}
	}
	else{
	}
}
RayeTree.prototype.scrollToView = function(item){
	if(null == item) return;
	var viewArea ={
		top:this.element.scrollTop,
		bottom:this.element.scrollTop + this.element.offsetHeight
	};
	var itemArea ={
		top:item.element.offsetTop,
		bottom:item.element.offsetTop + item.ue.icon.offsetHeight
	};
	if(itemArea.top >= viewArea.top && itemArea.bottom <= viewArea.bottom){
	}
	else if(itemArea.top < viewArea.top){
		this.element.scrollTop = item.element.offsetTop;
	}
	else{
		this.element.scrollTop = itemArea.bottom - this.element.offsetHeight;
	}
}
RayeTree.prototype.goDeep = function(path, cb){
	var idx = 0;
	var l = path.length;
	var e = null;
	var oThis = this;
var expandNext = function(start){
	start = start || false;
	if(!start){
		idx ++;
	}
	while(idx < l - 1){
		e = oThis.all[path[idx]];
		if(null == e){
setTimeout(function(){
	expandNext(true);
}
, 50);
return;
}
if(false == e.loaded){
e.expand(expandNext);
return;
}
else{
e.expand();
idx ++;
}
}
oThis.select(oThis.all[path[l - 1]]);
cb();
}
expandNext(true);
}
RayeTree.prototype.select = function(item, force){
	force = force || false;
	if(this.childNodes.selectedIndex[0] != item.index || true == force){
		this.childNodes.select(item.index);
		this.scrollToView(item);
		item.expand();
		if("function" == typeof this.eventListener.onselectchange){
			this.eventListener.onselectchange(item);
		}
	}
}
RayeTree.prototype.appendChild = function(item, o, f){
	var rootFlag = false;
	f = f || false;
	var ti = new RayeTreeItem(o.id, o.title, o.dataSource, o.icon,
	o.userData, f, item, this);
	if(null != item){
		item.appendChild(ti);
	}
	else{
		this.root = ti;
		this.element.appendChild(ti.element);
	}
	this.childNodes.add(ti);
	this.all[o.id] = ti;
	o = f = ti = null;
}
RayeTree.prototype.removeChild = function(item){
	var p = item.parent;
	var c = item.getChildNodes();
	var l = c.length;
	for(var i = 0;i < l;i ++){
		this.removeChild(c[i]);
	}
	delete this.all[item.id];
	this.childNodes.remove(item.index);
	if(null != p){
		p.removeChild(item);
	}
}
RayeTree.prototype.load = function(item, callback){
	callback = callback || null;
	var oThis = this;
	var p = item.parent
	var frontImg = item.frontImg;
	if(p != null){
		if(null != p){
			if(true == item.lastFlag){
				frontImg += "s";
			}
			else{
				frontImg += "i";
			}
		}
	}
	var LO = RayeTreeItem.loadingElement(frontImg);
	var te = Object();
	te.element = LO;
	te.index = 0;
	item.appendChild(te);
	var appended = false;
	this.readyState = 1;
	if("function" == typeof this.loadMethod){
var cb = function(e){
	if(!appended){
		appended = true;
	}
	else{
		return;
	}
	var l = e.length;
	item.removeChild(te);
	for(var i = 0;i < l;i ++){
		var o = e[i];
		var f = (i == l - 1);
		oThis.appendChild(item, o, f);
	}
	oThis.readyState = 4;
	if(callback){
		callback(item);
	}
}
item.loaded = true;
setTimeout(function(){
	oThis.loadMethod(item, cb);
}
,0);
}
}
function RayeTreeItem(id, title, dataSource, icon, userData, lastFlag, parent, tree){
	this.id = id;
	this.type = "treeItem";
	this.index = -1;
	this.title = title;
	this.dataSource= dataSource;
	this.icon = icon;
	this.userData = userData;
	this.parent = parent ||null;
	this.lastFlag = lastFlag || false;
	this.frontImg = "";
	this.tree = tree;
	if(parent != null){
		this.frontImg = parent.frontImg;
		var pp = parent.parent;
		if(null != pp){
			if(true == parent.lastFlag){
				this.frontImg += "s";
			}
			else{
				this.frontImg += "i";
			}
		}
	}
	this.element = RayeTreeItem.createElement(title, this.frontImg,
	(dataSource != ""), lastFlag, icon, (null == parent));
	var te = this.element;
	var imgs = this.element.getElementsByTagName("IMG");
	this.ue ={
		child:te.getElementsByTagName("DIV").item(0),
		icon:imgs.item(imgs.length - 1),
		expdr:(imgs.length > 1)?imgs.item(imgs.length - 2):null,
		label:te.getElementsByTagName("SPAN").item(0),
		item:te.getElementsByTagName("A").item(0)
	}
	this.loaded = false;
	this.expanded = false;
	this.element.instance = this;
}
RayeTreeItem.prototype.getChildNodes = function(){
	var e = this.ue.child.childNodes;
	var retval = [];
	var l = e.length;
	for(var i = 0;i < l;i ++){
		retval[i] = e.item(i).instance;
	}
	return retval;
}
RayeTreeItem.prototype.appendChild = function(e){
	this.ue.child.appendChild(e.element);
}
RayeTreeItem.prototype.removeChild = function(e){
	this.ue.child.removeChild(e.element);
}
RayeTreeItem.prototype.onselect = function(){
	this.ue.item.className = "treeItemSelected";
	if("" == this.icon){
		this.ue.icon.src = RayeTreeImg.system("of");
	}
}
RayeTreeItem.prototype.onblur = function(){
	this.ue.item.className = "";
	if("" == this.icon){
		this.ue.icon.src = RayeTreeImg.system("fd");
	}
}
RayeTreeItem.prototype.onindexchange = function(n){
	this.index = n;
}
RayeTreeItem.prototype.reload = function(){
	var oThis = this;
	if(4 != this.tree.readyState){
setTimeout(function(){
	oThis.reload();
}
,500);
return;
}
var e = [];
for(var a in this.tree.exp){
e[a] = this.tree.exp[a];
}
var si = null;
if(this.tree.childNodes.selectedIndex[0]){
si = this.tree.childNodes.item(this.tree.childNodes.selectedIndex[0]).id;
}
var tc = this.getChildNodes();
if(0 < tc.length){
var p = this;
}
else{
var p = this.parent;
if(null == p){
	p = this;
}
}
p.collapse();
p.loaded = false;
var c = p.getChildNodes();
var l = c.length;
for(var i = 0;i < l;i ++){
this.tree.removeChild(c[i]);
}
var oThis = this;
var expandFinish = function(item){
	var ic = item.getChildNodes();
	var l = ic.length;
	for(var i = 0;i < l; i++){
		if(e[ic[i].id]){
			ic[i].expand(expandFinish);
		}
	}
}
p.expand(expandFinish);
}
RayeTreeItem.prototype.expand = function(cb){
	if(!this.dataSource) return false;
	if(null != this.ue.expdr){
		if(this.lastFlag){
			this.ue.expdr.src = RayeTreeImg.system("lm");
		}
		else{
			this.ue.expdr.src = RayeTreeImg.system("tm");
		}
	}
	this.ue.child.style.display = "block";
	if(!this.loaded){
		this.tree.load(this, cb);
	}
	this.expanded = true;
	this.tree.exp[this.id] = true;
}
RayeTreeItem.prototype.collapse = function(){
	if(!this.dataSource) return false;
	if(this.ue.expdr){
		if(this.lastFlag){
			this.ue.expdr.src = RayeTreeImg.system("lp");
		}
		else{
			this.ue.expdr.src = RayeTreeImg.system("tp");
		}
	}
	this.ue.child.style.display = "none";
	this.expanded = false;
	delete this.tree.exp[this.id];
}
RayeTreeItem.prototype.toggle = function(){
	if(this.expanded){
		var so = this.tree.childNodes.item(this.tree.childNodes.selectedIndex[0]);
		if(so.index != this.index && RayeTree.contains(this.element, so.element)){
			this.tree.select(this);
		}
		this.collapse();
	}
	else{
		this.expand();
	}
}
RayeTreeItem.test = function(o){
	var retval = "";
	var tn = o.tagName.toUpperCase();
	var cn = String(o.className);
	if("SPAN" == tn){
		retval = "label";
	}
	else if("A" == tn){
		retval = "link";
	}
	else if(/Expdr/.test(cn)){
		retval = "expdr";
	}
	else if(/Icon/.test(cn)){
		retval = "icon";
	}
	return retval;
}
RayeTreeItem.parse = function(o){
	var retval = Array();
	var cn = o.childNodes;
	for (var i = 0;i < cn.length; i ++){
		var e = cn.item(i);
		var tag = e.tagName;
		if(typeof tag == "undefined") continue;
		var ec = e;
		do{
			ec = ec.firstChild;
		}
		while(null != ec && 3 != ec.nodeType && 4 != ec.nodeType);
		if(null == ec){
			retval[tag] = "";
		}
		else{
			retval[tag] = ec.nodeValue;
		}
	}
	var cn = o.attributes;
	for(var i = 0;i < cn.length;i ++){
		var t = cn.item(i);
		retval[t.nodeName] = t.nodeValue;
	}
	return retval;
}
RayeTree.contains = function(a, b){
	if("undefined" != typeof a.contains){
		return a.contains(b);
	}
	else{
		var bp = b.parentNode;
		var ap = a.parentNode;
		while(null != bp && bp != a && bp != ap){
			bp = bp.parentNode;
		}
		if(null == bp || bp == ap){
			return false;
		}
		else{
			return true;
		}
	}
}
RayeTreeItem.createElement = function(label, frontImg, hasChild, lastFlag, icon, root){
	var retval = document.createElement("DIV");
	var nobr = document.createElement("NOBR");
	var a = document.createElement("A");
	a.href = "javascript:void(0);";
	var img = document.createElement("IMG");
	var imgIcon = document.createElement("IMG");
	var span = document.createElement("SPAN");
	span.innerHTML = label;
	var divChild = document.createElement("DIV");
	divChild.className = "treeItemChild";
	frontImg = frontImg||"";
	hasChild = hasChild || false;
	lasFlag = lastFlag || false;
	icon = icon || "";
	root = root || false;
	var si = ""
	if(lastFlag){
		si = "l";
	}
	else{
		si = "t";
	}
	if(hasChild){
		si += "p";
	}
	img.src = RayeTreeImg.system(si);
	if("" == icon){
		imgIcon.src = RayeTreeImg.system("fd");
	}
	else{
		imgIcon.src = RayeTreeImg.custom(icon);
	}
	imgIcon.className = "treeIcon";
	retval.appendChild(nobr);
	nobr.appendChild(a);
	for(var i = 0;i < frontImg.length;i ++){
		var tImg = document.createElement("IMG");
		var ts = frontImg.substr(i,1);
		tImg.src = RayeTreeImg.system(ts);
		a.appendChild(tImg);
		tImg = null;
	}
	if(false == root){
		if(si.length == 2){
			img.className = "treeItemExpdr";
		}
		a.appendChild(img);
	}
	a.appendChild(imgIcon);
	a.appendChild(span);
	retval.appendChild(divChild);
	retval.className = "treeItem";
	span = nobr = img = imgIcon = t = divChild = null;
	return retval;
}
RayeTreeItem.loadingElement = function(frontImg){
	var retval = RayeTreeItem.createElement("载入中...", frontImg, false, true, "tree/loading.gif", false);
	retval.getElementsByTagName("SPAN").item(0).className = "treeItemDisabled";
	return retval;
}
RayeTree.getReal = function(o){
	var e = o;
	while(null != e && "undefined" == typeof e.instance){
		e = e.parentNode;
	}
	return e;
}
RayeTree.eventHandlers ={
	getEvent:function (e, el){
		if (!e){
			if (el)
			e = el.document.parentWindow.event;
			else
			e = window.event;
		}
		if (!e.srcElement){
			var el = e.target;
			while (el != null && el.nodeType != 1)
			el = el.parentNode;
			e.srcElement = el;
		}
		if (typeof e.offsetX == "undefined"){
			e.offsetX = e.layerX;
			e.offsetY = e.layerY;
		}
		return e;
	}
	,
	getDocument:function (e){
		if (e.target)
		return e.target.ownerDocument;
		return e.srcElement.document;
	}
	,
	ondblclick:function(e){
		e = RayeTree.eventHandlers.getEvent(e,this);
		var el = RayeTree.getReal(e.srcElement);
		var tree = el.instance.tree;
		if("function" == typeof tree.eventListener.ondblclick
		&& el.instance.index == tree.childNodes.selectedIndex[0]){
			tree.eventListener.ondblclick(el.instance);
		}
	}
	,
	onmousedown:function(e){
		e = RayeTree.eventHandlers.getEvent(e,this);
		var el = RayeTree.getReal(e.srcElement);
		var srcInstance = el.instance;
		var treeInstance = this.instance;
		if("treeItem" == srcInstance.type){
			var ct = RayeTreeItem.test(e.srcElement);
			switch(ct){
				case "icon":
				case "label":
				case "link":
				treeInstance.select(srcInstance);
				if("function" == typeof treeInstance.eventListener.ondragstart){
					treeInstance.eventListener.ondragstart(e, srcInstance);
				}
				break;
				case "expdr":
				srcInstance.toggle();
				break;
				default:
				break;
			}
		}
	}
	,
	oncontextmenu:function(e){
		var treeInstance = this.instance;
		if("function" == typeof treeInstance.eventListener.oncontextmenu){
			e = RayeTree.eventHandlers.getEvent(e,this);
			var el = RayeTree.getReal(e.srcElement);
			var srcInstance = el.instance;
			var nodeInstance = null;
			if("treeItem" == srcInstance.type){
				nodeInstance = srcInstance;
				if(treeInstance.childNodes.selectedIndex[0] != nodeInstance.index){
					treeInstance.childNodes.select(nodeInstance.index);
					treeInstance.scrollToView(nodeInstance);
				}
			}
			return treeInstance.eventListener.oncontextmenu(e, nodeInstance, treeInstance);
		}
		return true;
	}
}
function getOffset(o){
	var x = o.offsetLeft;
	var y = o.offsetTop;
	var e = o;
	while(e = e.offsetParent){
		x += e.offsetLeft;
		y += e.offsetTop;
	}
	return{
		left:x,top:y
	};
}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -