JS自定义树的实现



/**
 * <h3>树</h3>
 * 方法1:addRootNodes ->增加根节点
 * 方法2:addChild->>增加子节点
 * 说明:该脚本主要为了页面请求动态创建树节点。
 *     该树依赖于 css/tree.css, images图片 
 *     
 * @author IUPRG
 */


/**
 * 构造
 * @param   treeID:树容器的div ID
 */


var myTree=function(treeID){
	
	this.id = treeID;
	if (treeID) this.id = treeID;
	this.outerClassName = "treeUl";
	this.node = null;
	this.container = document.getElementById(this.id);
	this.container.innerHTML = ""; //clear innerHTML
	this.outer = document.createElement("ul");
	this.outer.className = this.outerClassName;
	this.container.appendChild(this.outer);
	this.arrClassName   = "foldArr";
 	this.idTag = treeID + "TnA"; //节点 a标签 id 前缀
	this.treeNodeIDTag = treeID + "Tn"; //节点  Node id 前缀
	this.curNode = function(){
		
	};//当前节点
	 
};
var termNode = function(){
	this.Id       = null; //节点id
	this.dataId   = null;//数据id
	this.element  = null;//li元素
	this.title    = "";//标题
	this.hasChild = 0; //是否包含子节点, 0:否 1:是
};




/**
 * 调试输出
 */
myTree.prototype.out=function(){

  alert(this.container.innerHTML);
};
/**
 * 清除容器innerHTML
 */
myTree.prototype.clear=function(){
	this.outer.innerHTML="";
	//alert(this.outer.id + "--innerHTML:");
};

myTree.prototype.ajaxGet =function(action,data,callback){
	$.ajax({type:'get',url:action,data:data,dataType:'json',cache:false,async: false,error:function(data){},success:callback});
};
/**
 * 清除节点 内容,以便增加新节点
 * 注意:此时只清除  UL ,li下的其他内容不可删除
 * @param node
 */
myTree.prototype.clearNode=function(node){
 
	var ul= this.getUl(node.element);
    if (ul) {
    	ul.innerHTML="";
    }else{
    	//移除li的子元素
    	if (node.hasChildNodes){
   		 var childs = node.childNodes;    
   		   for(var i = childs.length - 1; i >= 0; i--) {
   			   if (childs[i].nodeName.toUpperCase() =='LI'&&childs[i].nodeType==1) {
   				node.removeChild(childs[i]); 
   			   }
   		   }  
    	}
    	
    };
	
};

/**
 * 为指定的节点增加 “箭头”
 * @param node 
 */
myTree.prototype.addArrow=function(node){
	 
	var ul= this.getUl(node.element);
    if (ul==null||ul==undefined) {
    	var _ul=document.createElement("ul");
    	//node.appendChild(ul);
    	node.element.appendChild(_ul);
    	var ii=node.element.firstChild.firstChild;
    	if (ii) ii.className="foldArr";
    }
	
};
/**
 * 删除指定节点的"箭头"
 * @param node
 */
myTree.prototype.delArrow=function(node){
	 
	var ul= this.getUl(node.element);
    if (ul) {
    	node.element.removeChild(ul);
    	var ii=node.element.firstChild.firstChild;
    	if (ii) ii.className="";
    }
	
};

/**
 * 建立一个树的节点
 * @param id-节点的id,作为节点id的关键值
 * @param title-节点的标题
 * @param hasChild-是否包含子节点,0:不包含,当前节点属于叶子 1:包含
 * @param methodName-节点触发的js方法名,比如 "open(10)"
 * @returns dom元素
 */
myTree.prototype.createNode=function(id,title,hasChild,methodName){
	
	var li = document.createElement("li");
	
	var a = document.createElement("a");
	
	var iclassName="";
	
	a.href = "javascript:;";
	
	if (methodName){
		a.href = "javascript:" + methodName + ";";		
	}
	
	if (hasChild) {
		iclassName="class='"+this.arrClassName+"'";
	}
	
	if (!title) title="未知的标题或被移动的节点";
	
	a.title=title;
	 
	
	a.innerHTML="<i "+ iclassName + "></i><span>" + title +"</span>";
	//加入id
	if (id) {
		a.id= this.idTag + id;
		li.id = this.treeNodeIDTag + id;
		li.setAttribute("hasChild", (hasChild?1:0));
	}
	 
    li.appendChild(a);
    
    //如果包含子节点,则添加ul元素
    if (hasChild) {
    	
    	var ul =document.createElement("ul");
    	
    	li.appendChild(ul);
    	 
    }
    
    this.outer.appendChild(li);
    var node     =new termNode();
    node.element = li;
    node.title   = title;
    node.dataId  = id;
    node.Id = this.treeNodeIDTag + id;
    node.hasChild = (hasChild?1:0);
    return node;
};
/**
 * 增加根节点,根节点允许被增加多个,返回dom元素
 * @param id-节点的id,作为节点id的关键值
 * @param title-节点的标题
 * @param methodName-节点触发的js方法名,比如 "open(10)"
 * @returns dom元素
 */
myTree.prototype.addRootNode=function(id,title,hasChild,methodName){
	var node = this.createNode(id,title,hasChild,methodName);
    return node;//返回这个 节点 
    
};
/**
 * 增加子节点,返回dom元素.
 * @param id-节点的id,作为节点id的关键值
 * @param title-节点的标题
 * @param hasChild-是否包含子节点,0:不包含,当前节点属于叶子 1:包含
 * @param methodName-节点触发的js方法名,比如 "open(10)"
 * @returns dom元素
 */
myTree.prototype.addChild=function(pNode,id,title,hasChild,methodName){
    //
	var node = this.createNode(id,title,hasChild,methodName);
    //如果li下包含ul,则ul添加子节点
	var ul = this.getUl(pNode.element);
    if (ul) {
    	ul.appendChild(node.element);
    }else{//否则,就直接添加到li,作为叶子节点
    	pNode.element.appendChild(node.element);
    }
    //返回这个 子节点 
	return node;
};
/**
 * 根据id返回树节点
 * @param id
 * @returns
 */
myTree.prototype.getNode = function(id){
	this.curNode.Id= id;
	this.curNode.dataId= id.substr(this.treeNodeIDTag.length);//去掉开头的标记;
	this.curNode.element = document.getElementById(this.curNode.Id);
	this.curNode.title = this.curNode.element.textContent;
	this.curNode.hasChild = this.curNode.element.getAttribute("hasChild");
	return this.curNode;
};

/**
 * 根据dataId返回树节点(比如,根据外部指定的数据id,直接返回树节点)
 * @param dataId
 * @param isRefresh 是否刷新当前节点,true:从服务器获取最新数据,刷新当前节点 false:不刷新,只从document加载
 * @returns
 */
myTree.prototype.getNodeByDataId = function(dataId,isRefresh){
	var _this=this;
	this.curNode.Id       = this.treeNodeIDTag + dataId;
	this.curNode.dataId   = dataId;
	this.curNode.element  =  document.getElementById(this.curNode.Id);//$("#"+this.curNode.Id).get(0);
	this.curNode.title    = this.curNode.element.innerHTML;
	this.curNode.hasChild = this.curNode.element.getAttribute("hasChild");
	if (isRefresh&&isRefresh==true){
		this.ajaxGet(dolphin.term.action.refreshNodeAction,{termId:dataId},function(json){
			if (json&&json.result){
				if (json.result==1&&json.data){
					$(_this.curNode.element).find("a").title      =json.data.termName;
					$(_this.curNode.element).find("a i").innerHTML=json.data.termName;
					$(_this.curNode.element).find("a span").attr("title",json.data.termName);
					$(_this.curNode.element).find("a span").html(json.data.termName);
					_this.curNode.hasChild = json.data.hasChild;
					_this.curNode.title    = json.data.termName;
					 
				}
			}
		});
	}
	return this.curNode;
};

/**
 * 获取node节点里的ul元素
 * @param node
 * @returns
 */
myTree.prototype.getUl = function(node){
	if (node.hasChildNodes){
		 var childs = node.childNodes;    
		   for(var i = childs.length - 1; i >= 0; i--) {
			   if (childs[i].nodeName.toUpperCase() =='UL'&&childs[i].nodeType==1) {
				  return childs[i]; 
			   }
		   }  
	}
	return null;
};


  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
### 回答1: 我可以提供一些建议:1. 使用d3.js的数据可视化功能,可以让你的技能页面更加生动有趣;2. 使用d3.js的交互功能,可以让你的技能页面更加灵活,用户可以自定义它们的技能;3. 使用d3.js的动画功能,可以让你的技能页面更加生动,让用户更容易理解和记忆它们的技能。 ### 回答2: 使用d3.js实现一个自定义的技能页面是可行的。d3.js是一个流行的JavaScript库,用于创建动态、交互式的数据可视化。下面是实现这个页面的一般步骤: 1. 设计数据结构:定义一个数据结构来存储技能节点和连接信息。每个节点应该具有唯一的标识符、名称、描述以及与其他节点的连接关系。 2. 创建画布:使用d3.js创建一个SVG画布来承载技能。可以设置画布的宽度和高度来适应所需的展示区域。 3. 加载数据:将之前定义的数据结构加载到页面中。这可以通过从本地文件或通过Ajax请求获取远程数据来完成。 4. 渲染节点:使用d3.js的选择集来选择所有节点元素,并将其添加到SVG画布上。可以根据节点的数据绑定来设置节点的位置、样式和大小。 5. 绘制连接:使用d3.js的选择集来选择所有连接元素,并将其添加到SVG画布上。可以使用直线或曲线表示两个节点之间的连接。 6. 实现交互:使用d3.js的事件处理功能来实现节点和连接的交互。例如,可以通过点击节点来展开或收起子节点,或者通过鼠标悬停来显示详细信息。 7. 添加用户界面:为用户提供自定义能力的功能。可以使用HTML表单元素来让用户添加、修改或删除节点和连接。 8. 样式美化:使用CSS样式表来美化技能页面,并根据个人喜好进行自定义。 总结起来,通过d3.js实现一个自定义的技能页面需要设计数据结构、创建画布、加载数据、渲染节点、绘制连接、实现交互、添加用户界面和样式美化等步骤。通过这些步骤,可以实现一个具有自定义能力的交互式技能页面。 ### 回答3: 使用d3.js实现一个可以自定义的技能页面,可以按照以下步骤进行: 1. 准备数据:首先需要准备技能的数据,可以使用JSON格式存储每个技能及其相关属性,例如技能名称、描述、所需等级等。 2. 创建画布:使用d3.js创建一个SVG画布,用于展示技能页面。 3. 绘制节点:根据技能数据,使用d3.js绘制技能节点。你可以通过绘制圆形、矩形等形状来表示每个技能。 4. 连接节点:使用d3.js的连接函数,将各个节点连接起来,形成技能的结构。可以通过绘制直线或曲线来连接节点。 5. 添加文字和图标:根据技能数据,使用d3.js添加节点上的文字和图标。可以根据需要设置字体大小、颜色,并添加适当的图标来表示不同类型的技能。 6. 添加交互效果:使用d3.js的事件处理函数,为节点添加交互效果。例如,当鼠标悬停在节点上时,显示该技能的详细信息;点击节点时,可以展开或收起相关联的技能。 7. 自定义技能:提供一个界面,让用户可以自定义技能的结构和属性。例如,可以添加新的技能节点、修改技能节点的属性等。通过监听用户的操作,实时更新技能的展示。 8. 美化页面:根据需求,使用CSS样式来美化技能页面,使其更加吸引人。 通过以上步骤,你可以使用d3.js实现一个可以自定义的技能页面,用户可以根据自己的需求设计和展示自己的技能

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

安优小青和他的程序生活

我的文档对您有很大的帮助吗?

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值