js写简易树结构

html

<!--tab切换页--> 
<ul id="tabs">
  <li class="current"><a class="lia" href="#" rel="external nofollow" rel="external nofollow" rel="external nofollow" rel="external nofollow" title="tab1">日报</a></li>
  <li><a class="lia" href="#" rel="external nofollow" rel="external nofollow" rel="external nofollow" rel="external nofollow" title="tab2">月报</a></li>
  <li><a class="lia" href="#" rel="external nofollow" rel="external nofollow" rel="external nofollow" rel="external nofollow" title="tab3">季报</a></li>
  <li><a class="lia" href="#" rel="external nofollow" rel="external nofollow" rel="external nofollow" rel="external nofollow" title="tab4">年报</a></li>
  <li><a class="lia" href="#" rel="external nofollow" rel="external nofollow" rel="external nofollow" rel="external nofollow" title="tab5">自定义</a></li>
 </ul>
<!--弹窗-->
<div id="dialogBox2">
    <div id="allTree2" class="dialog_content"></div>
    <button onclick="submit('bumen')">确定</button>
	<button onclick="closeDialog('bumen')">关闭</button>
</div>
<!--tab标签页切换,多个选择流程-->
<label>选择部门:</label>
<input style="width: 425px" type="text" name="dept2" id="dept2" readonly/>
<button onclick="openDialog('bumen2')"> 选择</button>
 

js

$(document).ready(function () {
//页面加载时获取数据
    function getDept(){
				jQuery.ajax({
				async: false,
				   cache: false,
				   type: "POST",
				   url: horizon.paths.apppath+"/census/getDept.wf",
				   data: {},
				   dataType : "text",
				   success: function(res) {
				   var dept=JSON.parse(res);
				   let dataList=dept;
				    dataArr=setTreeData(dept);
				   }
			});
		}
}
//转换数据类型
function setTreeData(arr) {
                // 删除所有的children,以防止多次调用
                arr.forEach(function(item) {
                    delete item.children;
                });
                let map = {}; //构建map
                arr.forEach(function(i) {
                    map[i.id] = i; //构建以id为键 当前数据为值
                });
                let treeData = [];
                arr.forEach(function(child) {
                    let mapItem = map[child.parent_id]; //判断当前数据的parentId是否存在map中
                    if (mapItem) {
                        //存在则表示当前数据不是最顶层的数据
                        //注意: 这里的map中的数据是引用了arr的它的指向还是arr,当mapItem改变时arr也会改变,踩坑点
                        (mapItem.children || (mapItem.children = [])).push(child); //这里判断mapItem中是否存在child
                    } else {
                        //不存在则是顶层数据
                        treeData.push(child);
                    }
                });
                console.log(treeData)
                return treeData;
   }

//打开弹窗
	var doc=document;
        Back=doc.getElementById('black');
        DialogBox2=doc.getElementById('dialogBox2')
    function openDialog(arg) {
	    if(arg=="bumen"){
	    	ShowHide(true,Back,DialogBox2);
        	xuanran2(dataArr,0,30,"liucheng");
	    }
	    if(arg=="bumen2"){
	    	ShowHide(true,Back,DialogBox2);
        	xuanran2(dataArr,0,30,"liucheng2");
	    }
        if(arg=="bumen3"){
	    	ShowHide(true,Back,DialogBox2);
        	xuanran2(dataArr,0,30,"liucheng3");
	    }
	    if(arg=="bumen4"){
	    	ShowHide(true,Back,DialogBox2);
        	xuanran2(dataArr,0,30,"liucheng4");
	    }
	    if(arg=="bumen5"){
	    	ShowHide(true,Back,DialogBox2);
        	xuanran2(dataArr,0,30,"liucheng5");
	    }
    }
//弹框显示与隐藏
function ShowHide(Boolean,item1,item2) {
        for(var i=1,len=arguments.length;i<len;i++){
            if(Boolean){
                arguments[i].style.display="block";
            }else{
                arguments[i].style.display="none";
            };
        };
    }
//将树选择框渲染到页面上
    function xuanran2(data,deep,margin,type){
    var len = data.length;  //1 
		for (var i = 0; i < len; i++) {
    	   var app = document.getElementById('allTree2');
			//创建一个div标签
			var div = document.createElement("div");
			var div2 = document.createElement("div")
			//创建一个 input标签 代表 checkbox多选矿
			var checkbox = document.createElement('input');
			//创建一个 p标签代表文字
			var ptext = document.createElement('p');
			//将这个 名字放入p标签
			ptext.innerHTML = data[i].dept_name;
			//console.log(data[i].name)
			//设置 p标签的属性为 内联
			ptext.style.cssText = 'display: inline-block;';
			//给P标签添加一个class
			ptext.setAttribute('class', 'clickPtext');
			//设置input标签的类型  添加class
			checkbox.setAttribute('type', 'checkbox');
			checkbox.setAttribute('class', 'clickBox');
			//checkbox.setAttribute('onclick', 'clickBoxFun(this, false)');
 //给div标签添加 data-deep  和 data-show
			/**
			 * data-deep控制深度
			 * 初始深度为0  依次增加
			 * data-show控制子标签是显示还是隐藏
			 */
			div.setAttribute("data-deep", deep);
			div.setAttribute('data-show', '0');
			div.setAttribute('class', 'clicktext');
			//ptext.setAttribute('onclick','clickPtextFun(this, false)')
			div.style.cssText = 'cursor:pointer;margin-left: ' + (deep * margin) + 'px;';
 			
			
//将 checkbox 和 p 标签 一起写入 div  再将div输出到html中
			div.appendChild(checkbox);
			div.appendChild(ptext);
			app.appendChild(div);
			/*if(data[0].children){
				for(m=0;m<=data[0].children.length;m++){
					deep++;
				xuanran(data[0].children, deep, 30);
				}
			}*/
			//最开始 不把初级目录隐藏
			if(deep ==0 || deep==1){
				if(data[i].children){
					ptext.setAttribute('onclick','clickPtextFun(this, false)');	
					div.removeChild(checkbox);
				}else{
					div.onclick=(function(){
						checkBoxFun(this,"div",type);
					});
					checkbox.onclick=(function(){
						checkBoxFun(this,"checkbox",type);
					});
					//div.setAttribute('onclick','checkBoxFun(this,"div")');
					//checkbox.setAttribute('onclick','checkBoxFun(this,"checkbox")')
				}
				
			}else{
				div.onclick=(function(){
					checkBoxFun(this,"div",type);
				});
				checkbox.onclick=(function(){
					checkBoxFun(this,"checkbox",type);
				});
				//div.setAttribute('onclick','checkBoxFun(this,"div")');
				//checkbox.setAttribute('onclick','checkBoxFun(this,"checkbox")')
			}
			if(data[i].children){
				if (data[i].children.length > 0) {
				xuanran2(data[i].children, deep + 1, 30,type);
			}
			}
			
		}
    }
//点击内容和点击复选框都实现选中效果且不可多选。注:本人有多个选择部门的HTML
function checkBoxFun(obj,arg,type){
   console.log($(obj).find('input').prop("checked"))
    console.log(type)
    if(arg=="div"){
    	if(type=="liucheng"){ 
    		if($(obj).find('input').prop("checked")==true){
	    	 $(obj).find('input').prop("checked",false);
	    	 dayName="";
	    	 dayDept="";
	    }else{
	    	 $(".clicktext").not(this).find('input').prop("checked",false)
	    	//var aa= $(obj).find('input').siblings().prop("checked",false);
	    	$(obj).find('input').prop("checked",true);
	    	 dayName=$(obj).find('p').text();
	    	 dayDept=$(obj).find('p').text();
	    	}
    	}
    	if(type=="liucheng2"){
    		if($(obj).find('input').prop("checked")==true){
	    	 $(obj).find('input').prop("checked",false);
	    	 monthName="";
	    	 monthDept="";
	    }else{
	    	 $(".clicktext").not(this).find('input').prop("checked",false)
	    	//var aa= $(obj).find('input').siblings().prop("checked",false);
	    	$(obj).find('input').prop("checked",true);
	    	 monthName=$(obj).find('p').text();
	    	 monthDept=$(obj).find('p').text();
	    	}
    	}
    	if(type=="liucheng3"){
    		if($(obj).find('input').prop("checked")==true){
	    	 $(obj).find('input').prop("checked",false);
	    	 quarterName="";
	    	 quarterDept="";
	    }else{
	    	 $(".clicktext").not(this).find('input').prop("checked",false)
	    	//var aa= $(obj).find('input').siblings().prop("checked",false);
	    	$(obj).find('input').prop("checked",true);
	    	 quarterName=$(obj).find('p').text();
	    	 quarterDept=$(obj).find('p').text();
	    	}
    	}
    	if(type=="liucheng4"){
    		if($(obj).find('input').prop("checked")==true){
	    	 $(obj).find('input').prop("checked",false);
	    	 yearName="";
	    	 yearDept="";
	    }else{
	    	 $(".clicktext").not(this).find('input').prop("checked",false)
	    	//var aa= $(obj).find('input').siblings().prop("checked",false);
	    	$(obj).find('input').prop("checked",true);
	    	 yearName=$(obj).find('p').text();
	    	 yearDept=$(obj).find('p').text();
	    	}
    	}
    	if(type=="liucheng5"){
    		if($(obj).find('input').prop("checked")==true){
	    	 $(obj).find('input').prop("checked",false);
	    	 customName="";
	    	 customDept="";
	    }else{
	    	 $(".clicktext").not(this).find('input').prop("checked",false)
	    	//var aa= $(obj).find('input').siblings().prop("checked",false);
	    	$(obj).find('input').prop("checked",true);
	    	 customName=$(obj).find('p').text();
	    	 customDept=$(obj).find('p').text();
	    	}
    	}
    	
    }else {
	    if(type=="liucheng"){
	    	if($(obj).prop("checked")==true) {
    		$(obj).prop("checked",false);
    		dayName="";
    		dayDept="";
    	}else{
	   		 $(".clickBox").not(this).prop("checked",false);
	    	 $(obj).prop("checked",true);
	    	 dayName=$(obj).find('p').text();
	    	 dayDept=$(obj).find('p').text();
    		}
	    }
	    if(type=="liucheng2"){
	    	if($(obj).prop("checked")==true) {
    		$(obj).prop("checked",false);
    		monthName="";
    		monthDept="";
    	}else{
	   		 $(".clickBox").not(this).prop("checked",false);
	    	 $(obj).prop("checked",true);
	    	 monthName=$(obj).find('p').text();
	    	 monthDept=$(obj).find('p').text();
    		}
	    }
	    if(type=="liucheng3"){
	    	if($(obj).prop("checked")==true) {
    		$(obj).prop("checked",false);
    		quarterName="";
    		quarterDept="";
    	}else{
	   		 $(".clickBox").not(this).prop("checked",false);
	    	 $(obj).prop("checked",true);
	    	 quarterName=$(obj).find('p').text();
	    	 quarterDept=$(obj).find('p').text();
    		}
	    }
	    if(type=="liucheng4"){
	    	if($(obj).prop("checked")==true) {
    		$(obj).prop("checked",false);
    		yearName="";
    		yearDept="";
    	}else{
	   		 $(".clickBox").not(this).prop("checked",false);
	    	 $(obj).prop("checked",true);
	    	 yearName=$(obj).find('p').text();
	    	 yearDept=$(obj).find('p').text();
    		}
	    }
	    if(type=="liucheng5"){
	    	if($(obj).prop("checked")==true) {
    		$(obj).prop("checked",false);
    		customName="";
    		customDept="";
    	}else{
	   		 $(".clickBox").not(this).prop("checked",false);
	    	 $(obj).prop("checked",true);
	    	 customName=$(obj).find('p').text();
	    	 customDept=$(obj).find('p').text();
    		}
	    }
    	
    }	
   }
/**
	 * 控制菜单显示隐藏
	 * @param obj  点击的元素
	 * @param is   是否隐藏, true 为再次点击后不隐藏, false 再次点击后隐藏
	 */
	 var is=false;
	function clickPtextFun(obj, is) { 
		//点击的p 父元素的所有下面的兄弟元素
		var nextBro = $(obj).parent().nextAll();
		//点击的p的父元素
		var div = $(obj).parent();
		console.log(nextBro.data('deep'))
		console.log(div.data('deep'))
		for (var i = 0; i < nextBro.length; i++) {		
			//当它下面的所有兄弟元素的深度 比他大一个数时, 代表他的儿子元素, 否则退出。 因为不比他大的都是兄弟元素或者父元素
			if ($(nextBro[i]).data('deep') == div.data('deep') + 1) {
			console.log(div.data('deep'))
				if (div.data('show') == 0 || div.data('show') == '0') {
					$(nextBro[i]).show();
				} else {
					if (!is) {
						$(nextBro[i]).hide();
					}
				}
			} else {
				break;
			}
		}
		div.data('show', (div.data('show') + 1) % 2);
	}
/**
	 * 选框控制
	 * @param obj
	 */
	function clickBoxFun(obj) {
		//当第一次点击选框后, 将列表展开  true为再次点击不隐藏
		clickPtextFun(obj, true);
		//点击的checkbox 父元素的所有下面的兄弟元素
		var nextBro = $(obj).parent().nextAll();
		//点击的checkbox的父元素
		var thisDiv = $(obj).parent();
		for (var i = 0; i < nextBro.length; i++) {
			//当他下面的深度大于它时, 全部选中, 否则就退出。 因为小于或等于的 都是兄弟元素或者父元素
			if ($(nextBro[i]).data('deep') > thisDiv.data('deep')) {
				if (thisDiv.find('input').is(':checked')) {
					$(nextBro[i]).find('input').prop('checked', true);
				} else {
					$(nextBro[i]).find('input').prop('checked', false);
				}
			} else {
				break;
			}
		}
 
	}
//确定并关闭弹框
	function submit(arg){
		if(arg=="bumen"){
			if(dayDept!=""){
				jQuery("#dept").prop('value',dayDept);
			  	ShowHide(false,Back,DialogBox2);
	        	document.getElementById("allTree2").innerHTML="";
	        	dayDept="";
	        	return;
			}
			if(monthDept!=""){
				jQuery("#dept2").prop('value',monthDept);
			  	ShowHide(false,Back,DialogBox2);
	        	document.getElementById("allTree2").innerHTML="";
	        	monthDept="";
	        	return;
			}
			if(quarterDept!=""){
				jQuery("#dept3").prop('value',quarterDept);
			  	ShowHide(false,Back,DialogBox2);
	        	document.getElementById("allTree2").innerHTML="";
	        	quarterDept="";
	        	return;
			}
			if(yearDept!=""){
				jQuery("#dept4").prop('value',yearDept);
			  	ShowHide(false,Back,DialogBox2);
	        	document.getElementById("allTree2").innerHTML="";
	        	yearDept="";
	        	return;
			}
			if(customDept!=""){
				jQuery("#dept5").prop('value',customDept);
			  	ShowHide(false,Back,DialogBox2);
	        	document.getElementById("allTree2").innerHTML="";
	        	customDept="";
	        	return;
			}
			parent.horizon.notice.warning("请选择部门");
		}
	}

遇到的问题:

1、弹框关闭在打开数据重复。

解决:关闭弹框后要清空数据

document.getElementById("allTree2").innerHTML="";

2、prop()和attr()

prop是标签自带属性都可以操作。

attr操作自己定义的属性。

3、setAttribute('onclick','function')传参问题。

setAttribute('onclick','checkBoxFun(this,"div",type)')动态给创建的标签添加点击事件

param只能传固定参数,传变量的话调用的函数获取不到,报undefined。例:type报undefined

解决:div.οnclick=(function(){
                    checkBoxFun(this,"div",type);
                });

参考文章:https://blog.csdn.net/just_for_your_smile/article/details/78582141

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值