web端树状菜单(支持无限下级分类+修改+新增+删除)

 树状菜单

DEMO下载:https://download.csdn.net/download/zhi_jie/10825201 

一开始在onethink后台里看到的,发现只能展开到3级菜单,经过我一通修改,可以无限下级分类的菜单了 ,可以实时修改、新增、删除,代码示例需要jquery与art-template.js(可以换成你习惯的模板引擎或修改成jq操作)

注意:此树状菜单是一级一级读取json数据的,点击才会触发下级分类,不是一次性读取所有树状结构数据,这样可以减轻些读取压力吧。

json数据结构:

{
	"infor":[
        {"id":"01", "title":"赤峰市森林公安局", "link":"json/02bangong.js"},
        {"id":"02", "title":"自治区森林公安局", "link":"json/02bangong.js"},
        {"id":"03", "title":"巴林左旗森林公安局", "link":"json/02bangong.js"},
        {"id":"04", "title":"松山区", "link":"json/02bangong.js"},
        {"id":"05", "title":"红山区", "link":"json/02bangong.js"},
        {"id":"06", "title":"赤峰市林业局", "link":"json/02bangong.js"}
    ]
}

 link:是下级分类数据的地址,当点击时才会触发。

顺便科普个小知识,谷歌浏览器在启动快捷方式地址后 --allow-file-access-from-files即可本地Ajax数据了。

页面上的“+”“-”class图标样式使用了Font Awesome的,你可下载使用或换成自己的

html:

<!DOCTYPE html>
<html lang="zh-cn">
<head>
	<meta http-equiv="Content-Type" content="text/html;charset=UTF-8">
	<title>树状菜单 | 夕空</title>
	<script src="http://apps.bdimg.com/libs/jquery/1.11.3/jquery.min.js"></script>
	<script src="https://aui.github.io/art-template/js/template-engines/template-web.js"></script>
	<link rel="stylesheet" href="http://netdna.bootstrapcdn.com/font-awesome/4.7.0/css/font-awesome.min.css">
	<style type="text/css">
	html,body{margin: 0;padding: 0;height: 100%;}
/*---------------------*\
 * 树形菜单(支持多级)
\*---------------------*/
.tree {
	width: 90%;margin: 20px auto;
    min-height:20px; padding:19px; margin-bottom:20px;border:1px solid #ccc;
    -webkit-border-radius:4px;-moz-border-radius:4px; border-radius:4px;
    -webkit-box-shadow:inset 0 1px 1px rgba(0, 0, 0, 0.05);
    -moz-box-shadow:inset 0 1px 1px rgba(0, 0, 0, 0.05);
    box-shadow:inset 0 1px 1px rgba(0, 0, 0, 0.05)
}
.tree ul{padding-left: 40px;font-size: 14px;}
.tree li {
    padding:0.6em 0 0 5px; margin:0; list-style-type:none; position:relative
}
.tree li::before, .tree li::after {
    content:''; left:-20px; position:absolute;
}
.tree li::before {
    border-left:1px dotted #999; height:100%; top:0; width:1px
}
.tree li::after {
    top:1.9em; border-top:1px dotted #999; width:25px;
}
.tree li>span {
    line-height: 2.6em;-moz-border-radius:5px; -webkit-border-radius:5px; border-radius:5px; border:1px solid #bbb;
    display:inline-block; padding:0 30px 0 8px; text-decoration:none
}
.tree li.parent_li>span {
    cursor:pointer
}
.tree>ul>li::before, .tree>ul>li::after {
    border:0
}
.tree li:last-child::before {
    height:1.9em
}
.tree li.parent_li>span:hover, .tree li.parent_li>span:hover+ul li span {
    background:#D3F0D2; border:1px solid #5FA196; color:#000
}
.tree li:hover>span{background: #D8EBF0;border:1px solid #2764C8;}
.tree form{display: inline;}
.tree input[type=text]{line-height: 22px; font-size: 15px; background-color: rgba(255,255,255,0.3);border: none;}
.tree input[type=text]:hover{background-color: #FFF;border: none;}
 
	</style>
 
 
</head>
<body>
	<br>
	<div class="tree">
		<ul>
		</ul>
	</div>
 
	<br>
	<a href="http://www.flashme.cn">www.flashme.cn</a>
 
	<div id="newtree" style="display: none;">
		<li>
			<span>
				<i></i>
				<form class="add" action="这里是新增子项的处理地址 form:upid|title" method="post" >
					<input type="hidden" name="upid" value="">
					<input type="text" name="title" class="text" value="" placeholder="请填写名称">
					<input type="button" class="treeset" value="确定" />
				</form>
			</span>
			<ul></ul>
		</li>
	</div>
 
	<script type="text/html" id="tree-art">
		{{each infor as value i}}
		<li {{if value.link}}class="parent_li"{{/if}}>
			<span data-link="{{value.link}}">
				<i class="fa {{if value.link}}fa-plus-square-o{{/if}}"></i>
				<form class="list" action="这里是表单实时更新地址 form:id|title" method="post" >
					<input type="hidden" name="id" value="{{value.id}}">
					<input type="text" name="title" class="text" value="{{value.title}}">
				</form>
				<form class="del" action="删除目标的地址 form:id" method="post" >
					<input type="hidden" name="id" value="{{value.id}}">
					<input type="button" class="treedel" value="删除" />
				</form>
				<input type="button" class="treeadd" value="新增" />
			</span>
			<ul></ul>
		</li>
		{{/each}}
	</script>
 
	<script type="text/javascript">
		//==========================================树形菜单
		function tree(){
			$('.tree').on('click','li.parent_li > span', function (e) {
				var children = $(this).siblings('ul');
				if(children.children('li').length==0){
					return;
				}
				treesub(children,$(this),false);
				e.stopPropagation();
			});
			$('.tree li:has(ul)').addClass('parent_li');
		}
		function treesub($target,ev,open){
			if ($target.is(":visible") && open==false) {
				$target.hide('fast');
				ev.attr('title', '展开分支').find(' > i').addClass('fa-plus-square-o').removeClass('fa-minus-square-o');
			} else {
				$target.show('fast');
				ev.attr('title', '收起分支').find(' > i').addClass('fa-minus-square-o').removeClass('fa-plus-square-o');
			}
		}
 
		//初始树状菜单点击事件
		tree();
 
		function getLinkage(url,$target){
			$.ajax({
				url:url,
				dataType:"json",
				success:function(ev){
 
					//----显示下级菜单
					$target.children('ul').hide();//先隐藏
					var treehtml = template('tree-art', ev);
					$target.children('ul').append(treehtml);
					treesub($target.children('ul'),$target.children('span'),true);//后显示
					//----
				},
				error: function (XHR) {
					console.log(XHR.status);
				}
			})
		}
		//--------------初始第一级列表::
		getLinkage("json/01danwei.js", $('.tree'));
 
		//初始加载子集
		$('.tree').on('click','li>span',function(){
			var link=$(this).data('link');
			if(link && $(this).siblings('ul').children('li').length==0){
				getLinkage(link,$(this).parent());
			}
		})
 
		/* 实时更新分类信息 */
		$(".tree")
		.on("submit", "form.list", function(){
			var self = $(this);
			$.post(
				self.attr("action"),
				self.serialize(),
				function(data){
					/* 提示信息 */
					alert('返回提示...')
				},
				"json"
				);
			return false;
		})
		.on("focus","input[type=text]",function(){
			$(this).data('param',$(this).closest("form").serialize());
 
		})
		.on("blur", "input[type=text]", function(){
			if($(this).data('param')!=$(this).closest("form").serialize()){
				$(this).closest("form").submit();//提交父级form
			}
		})
		.on("click", "input[type=text]", function(e){e.stopPropagation();});
 
		// ==========================================新增子项
		$(".tree")
		.on("submit", "form.add", function(){
			var self = $(this);
			$.post(
				self.attr("action"),
				self.serialize(),
				function(data){
					//重载
					var closeul=self.closest("ul");
					closeul.html("");
					closeul.siblings('span').trigger("click");
					closeul.parent("li").addClass('parent_li');
 
					/* 提示信息 */
					alert('返回提示...')
				},
				"json"
				);
			return false;
		})
		//新增按钮事件
		$('.tree').on('click','.treeadd',function(e){
			var parent=$(this).parent().parent();
			if(parent.find('ul>li').length==0){
				parent.children('span').trigger("click");
			}
			var newadd=$($('#newtree').html());
			newadd.find('input[name=upid]').val($(this).parent().find('input[name=id]').val());
			parent.children('ul').prepend(newadd);
			treesub(parent.children('ul'),parent.children('span'),true);
			e.stopPropagation();
		})
		//确认存储提交
		$('.tree').on('click','.treeset',function(e){
			$(this).closest("form").submit();
		})
 
		// ==========================================删除菜单项
		$(".tree")
		.on("submit", "form.del", function(){
			var self = $(this);
			$.post(
				self.attr("action"),
				self.serialize(),
				function(data){
					//清除自身(子分类也会一起清除)
					self.closest("li").remove();
 
					/* 提示信息 */
					alert('返回提示...')
				},
				"json"
				);
			return false;
		})
		$('.tree').on('click','.treedel',function(e){
			if(confirm('确实要删除该菜单吗?')){
				$(this).closest("form").submit();
			}
			e.stopPropagation();
		})
 
	</script>
</body>
</html>

如果嫌上面的菜单尺寸太大,下面是精简版,控制ul里的font-size大小即可缩放整个大小:

<!DOCTYPE html>
<html lang="zh-cn">
<head>
	<meta http-equiv="Content-Type" content="text/html;charset=UTF-8">
	<title>树状菜单 精简版 | 夕空</title>
	<script src="http://apps.bdimg.com/libs/jquery/1.11.3/jquery.min.js"></script>
	<script src="https://aui.github.io/art-template/js/template-engines/template-web.js"></script>
	<link rel="stylesheet" href="http://netdna.bootstrapcdn.com/font-awesome/4.7.0/css/font-awesome.min.css">
	<style type="text/css">
	html,body{margin: 0;padding: 0;height: 100%;}
/*---------------------*\
 * 树形菜单(支持多级)
\*---------------------*/
.tree {
	width: 90%;margin: 20px auto;
    min-height:20px; padding:19px; margin-bottom:20px;border:1px solid #ccc;
    -webkit-border-radius:4px;-moz-border-radius:4px; border-radius:4px;
    -webkit-box-shadow:inset 0 1px 1px rgba(0, 0, 0, 0.05);
    -moz-box-shadow:inset 0 1px 1px rgba(0, 0, 0, 0.05);
    box-shadow:inset 0 1px 1px rgba(0, 0, 0, 0.05)
}
.tree ul{padding-left: 20px;font-size: 16px;}
.tree li {
    list-style-type:none; margin:0; padding:0 0 0 5px; position:relative
}
.tree li::before, .tree li::after {
    content:''; left:-10px; position:absolute;
}
.tree li::before {
    border-left:1px dotted #999; height:100%; top: 0; width:1px
}
.tree li::after {
    border-top:1px dotted #999; top:1em; width:17px;
}
.tree li>span {
    border-bottom:1px solid #f0f0f0;line-height: 2em;
    display:inline-block; padding:0 20px 0 8px; text-decoration:none
}
.tree li.parent_li>span {
    cursor:pointer
}
.tree>ul>li::before, .tree>ul>li::after {
    border:0
}
.tree li:last-child::before {
    height:1em
}
.tree li.parent_li>span:hover, .tree li.parent_li>span:hover+ul li span {
    background:#D3F0D2; border-bottom:1px solid #5FA196; color:#000
}
.tree li:hover>span{background: #D8EBF0;border-bottom:1px solid #2764C8;}
.tree form{display: inline;}
.tree input[type=text]{line-height: 22px; font-size: 14px; background-color: rgba(255,255,255,0.3);border: none;}
.tree input[type=text]:hover{background-color: #FFF;border: none;}
 
	</style>
 
 
</head>
<body>
	<br>
	<div class="tree">
		<ul>
		</ul>
	</div>
 
	<br>
	<a href="http://www.flashme.cn">www.flashme.cn</a>
 
	<div id="newtree" style="display: none;">
		<li>
			<span>
				<i></i>
				<form class="add" action="这里是新增子项的处理地址 form:upid|title" method="post" >
					<input type="hidden" name="upid" value="">
					<input type="text" name="title" class="text" value="" placeholder="请填写名称">
					<input type="button" class="treeset" value="确定" />
				</form>
			</span>
			<ul></ul>
		</li>
	</div>
 
	<script type="text/html" id="tree-art">
		{{each infor as value i}}
		<li {{if value.link}}class="parent_li"{{/if}}>
			<span data-link="{{value.link}}">
				<i class="fa {{if value.link}}fa-plus-square-o{{/if}}"></i>
				<form class="list" action="这里是表单实时更新地址 form:id|title" method="post" >
					<input type="hidden" name="id" value="{{value.id}}">
					<input type="text" name="title" class="text" value="{{value.title}}">
				</form>
				<form class="del" action="删除目标的地址 form:id" method="post" >
					<input type="hidden" name="id" value="{{value.id}}">
					<input type="button" class="treedel" value="删除" />
				</form>
				<input type="button" class="treeadd" value="新增" />
			</span>
			<ul></ul>
		</li>
		{{/each}}
	</script>
 
	<script type="text/javascript">
		//==========================================树形菜单
		function tree(){
			$('.tree').on('click','li.parent_li > span', function (e) {
				var children = $(this).siblings('ul');
				if(children.children('li').length==0){
					return;
				}
				treesub(children,$(this),false);
				e.stopPropagation();
			});
			$('.tree li:has(ul)').addClass('parent_li');
		}
		function treesub($target,ev,open){
			if ($target.is(":visible") && open==false) {
				$target.hide('fast');
				ev.attr('title', '展开分支').find(' > i').addClass('fa-plus-square-o').removeClass('fa-minus-square-o');
			} else {
				$target.show('fast');
				ev.attr('title', '收起分支').find(' > i').addClass('fa-minus-square-o').removeClass('fa-plus-square-o');
			}
		}
 
		//初始树状菜单点击事件
		tree();
 
		function getLinkage(url,$target){
			$.ajax({
				url:url,
				dataType:"json",
				success:function(ev){
 
					//----显示下级菜单
					$target.children('ul').hide();//先隐藏
					var treehtml = template('tree-art', ev);
					$target.children('ul').append(treehtml);
					treesub($target.children('ul'),$target.children('span'),true);//后显示
					//----
				},
				error: function (XHR) {
					console.log(XHR.status);
				}
			})
		}
		//--------------初始第一级列表::
		getLinkage("json/01danwei.js", $('.tree'));
 
		//初始加载子集
		$('.tree').on('click','li>span',function(){
			var link=$(this).data('link');
			if(link && $(this).siblings('ul').children('li').length==0){
				getLinkage(link,$(this).parent());
			}
		})
 
		/* 实时更新分类信息 */
		$(".tree")
		.on("submit", "form.list", function(){
			var self = $(this);
			$.post(
				self.attr("action"),
				self.serialize(),
				function(data){
					/* 提示信息 */
					alert('返回提示...')
				},
				"json"
				);
			return false;
		})
		.on("focus","input[type=text]",function(){
			$(this).data('param',$(this).closest("form").serialize());
 
		})
		.on("blur", "input[type=text]", function(){
			if($(this).data('param')!=$(this).closest("form").serialize()){
				$(this).closest("form").submit();//提交父级form
			}
		})
		.on("click", "input[type=text]", function(e){e.stopPropagation();});
 
		// ==========================================新增子项
		$(".tree")
		.on("submit", "form.add", function(){
			var self = $(this);
			$.post(
				self.attr("action"),
				self.serialize(),
				function(data){
					//重载修改的部分
					var closeul=self.closest("ul");
					closeul.html("");
					closeul.siblings('span').trigger("click");
					closeul.parent("li").addClass('parent_li');
 
					/* 提示信息 */
					alert('返回提示...')
				},
				"json"
				);
			return false;
		})
		//新增按钮事件
		$('.tree').on('click','.treeadd',function(e){
			var parent=$(this).parent().parent();
			if(parent.find('ul>li').length==0){
				parent.children('span').trigger("click");
			}
			var newadd=$($('#newtree').html());
			newadd.find('input[name=upid]').val($(this).parent().find('input[name=id]').val());
			parent.children('ul').prepend(newadd);
			treesub(parent.children('ul'),parent.children('span'),true);
			e.stopPropagation();
		})
		//确认存储提交
		$('.tree').on('click','.treeset',function(e){
			$(this).closest("form").submit();
		})
 
		// ==========================================删除菜单项
		$(".tree")
		.on("submit", "form.del", function(){
			var self = $(this);
			$.post(
				self.attr("action"),
				self.serialize(),
				function(data){
					//清除自身(子分类也会一起清除)
					self.closest("li").remove();
 
					/* 提示信息 */
					alert('返回提示...')
				},
				"json"
				);
			return false;
		})
		$('.tree').on('click','.treedel',function(e){
			if(confirm('确实要删除该菜单吗?')){
				$(this).closest("form").submit();
			}
			e.stopPropagation();
		})
 
	</script>
</body>
</html>

 

  • 0
    点赞
  • 6
    收藏
    觉得还不错? 一键收藏
  • 4
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值