前端JS简单实现树形功能

本文介绍了一个使用原生JavaScript编写的树形列表插件,通过JSON数据结构动态渲染,包括展开/折叠功能,展示了如何在HTML和CSS中实现节点的层次结构和交互效果。

显示效果:

附完整代码:

<!DOCTYPE html>
<html>
<head>
	<meta charset="utf-8">
	<meta name="viewport" content="width=device-width, initial-scale=1.0">
	<title>原生JS-树形</title>
</head>
<body>
	<div id="treelists"></div>
</body>
<style>
	.mo-treelists{ width: 100%; display: block; overflow: hidden; float: left; box-sizing: border-box; padding: 10px 0;}
	.mo-treelists .treelists-li{ width: 100%; display: block; overflow: hidden; box-sizing: border-box; padding-left: 20px;}
	.mo-treelists .treelists-li input{ float: left; margin: 11px 8px 0 0;}
	.mo-treelists .treelists-txt{ float: left; line-height: 36px; display: block; overflow: hidden; box-sizing: border-box; cursor: pointer; position: relative; padding-left: 16px; transition: all .3s;}
	.mo-treelists .treelists-txt::after{ content: '▶'; position: absolute; line-height: inherit; left: 0; font-size: 12px; color: #eee;}
	.mo-treelists .treelists-txt.next::after{ color: #999;}
	.mo-treelists .treelists-txt.next.active::after{ content: '▼';}
	.mo-treelists .treelists-sub{ width: 100%; display: none; overflow: hidden; box-sizing: border-box; border-left: 1px dashed #eee;}
</style>
<script>
	let data = [
		{'id':'1','txt':'一级分类',pid:'0'},
		{'id':'2','txt':'一级分类',pid:'0'},
		{'id':'22','txt':'一级分类',pid:'0'},
		{'id':'3','txt':'二级分类',pid:'1'},
		{'id':'4','txt':'二级分类',pid:'1'},
		{'id':'5','txt':'二级分类',pid:'1'},
		{'id':'6','txt':'二级分类',pid:'1'},
		{'id':'7','txt':'三级分类',pid:'3'},
		{'id':'8','txt':'三级分类',pid:'3'},
		{'id':'9','txt':'三级分类',pid:'3'},
		{'id':'10','txt':'三级分类',pid:'4'},
		{'id':'11','txt':'三级分类',pid:'4'},
		{'id':'12','txt':'三级分类',pid:'4'},
		{'id':'13','txt':'四级分类',pid:'10'},
		{'id':'14','txt':'四级分类',pid:'10'},
	]
		
	
	let paras = {};
	paras['thisbox'] = document.querySelector('#treelists');
	paras['datas'] = data;
	paras['pids'] = '0';
	paras['backfun'] = function(id,txt,pid){
		console.log('选中的数据:',id,txt,pid)
	};
	let tree = new moTreeList(paras);
	
	// 第二种引用方式
	// moTreeList(document.querySelector('#treelists'),data,'1',function(id,txt,pid){
	// 	console.log(id,txt,pid)
	// });
	
		
		
	//多级树形图
	//@ paras  thisbox:容器 *
	//@ paras  datas:数据 数据结构[{id:'',pid:'',txt:''}] *
	//@ paras  pids:默认0 层级ID
	//@ paras  backfun:返回已选择数据data 数据结构[{id:'',pid:'',txt:''}] *
	function moTreeList(thisbox,datas,pids,backfun){
		let tl = this;
		tl.boxs = thisbox.thisbox || thisbox;
		tl.data = thisbox.datas || datas;
		tl.pid = thisbox.pids || pids;
		tl.backfun = thisbox.backfun || backfun;
		
		let tbox = levelDom(tl.boxs,'div','mo-treelists');
		moTreeListLi(tbox,tl.data,tl.pid)
		
		//渲染列表
		function moTreeListLi(box,data,id){
			if(data.length > 0){
				for(let i = 0; i < data.length; i++){
					if(data[i].pid == id){
						let li = levelDom(box,'div','treelists-li');
						let txt = levelDom(li,'a','treelists-txt',data[i].txt);
						txt.setAttribute('id',data[i].id);
						
						//递归
						let  sub= levelDom(li,'div','treelists-sub');
						moTreeListLi(sub,data,data[i].id)
						
						//判断有无子集
						if(sub.innerHTML != ''){
							txt.classList.add('next');
						}else{
							txt.nextElementSibling.remove();
						}
						txt.onclick = function(){
							tl.backfun(data[i].id,data[i].txt,data[i].pid);
							let is_sub = this.nextElementSibling;
							if(is_sub){
								if(is_sub.style.display == 'block'){
									this.classList.remove('active');
									is_sub.style.display = 'none';
								}else{
									this.classList.add('active');
									is_sub.style.display = 'block';
								}
							}
						}
					}
				}
			}else{
				box.innerHTML='<div style="color:#f56c6c; text-align:center;">暂无数据~</div>'
			}
		}
	}
	
	//节点创建
	//pobj父节点 ,dtag节点类型,dclass节点类名 ,dtxt节点文本
	function levelDom(pobj,dtag,dclass,dtxt){
		var obj = document.createElement(dtag);
		if(dtxt) obj.innerHTML = dtxt;
		if(dclass) obj.setAttribute("class",dclass);
		pobj.appendChild(obj);
		return obj;
	}
	</script>
</html>

评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值