前言
看到许多伙伴们对这个功能效果挺感兴趣的,鄙人捂着颓废的肝,给你们补上。
效果
请移步到上一篇:jquery文件菜单拓展《一》-CSDN博客
Java对象和传入页面的json数据
请移步到:手写jquery生成无限极的菜单-CSDN博客
废话不多说,直接上代码
代码
html:
<div class="parent"> <ul class="parent_ul" style="background-color: whitesmoke; width: 20%"></ul> </div> <ul class="opr"> <!--添加文件的按钮--> <li><span class="opr-span glyphicon glyphicon-file" id="file"></span></li> <!--添加文件夹的按钮--> <li><span class="opr-span glyphicon glyphicon-folder-close" id="folder"></span></li> </ul>
复制
css:
li{ margin-left: 10%; list-style-type: none; /*disclosure-closed*/ } .opr-span{ width: 20%; } .glyphicon-remove{ color: red; } .fa-save{ color: orange; } .opr li{ display:inline-block; } .opr{ width: 100px; position: absolute; } .new-li{ margin: 0%; width: 100%; }
复制
JS
<script type="text/javascript" > var $opr = $(".opr"); $(function (){ $opr.hide(); init(); closeAndOpen(); // $("ul li .menu-ul").hide(); }); var $body = $("body"); var $oprli = $(".opr li"); /** * 开光 */ function closeAndOpen(){ let _this; var isCreatSpan; var isfile =$(this).hasClass("glyphicon-file"); $body.on("click contextmenu",".menu-ul li span",function (e) { isCreatSpan = $(this).hasClass("menu-span"); var children = $(this).parent().children(".menu-ul"); if (e.type==="click" && !isfile){ //console.log($(this)) if (isCreatSpan){ children.toggle(500); e.stopPropagation(); $(this).toggleClass(function (){ if ($(this).is("menu-span glyphicon-folder-close")){ return "menu-span glyphicon-folder-close "; } return "glyphicon-folder-open";}); } } if (e.type==="contextmenu" && !isfile && isCreatSpan){ e.preventDefault(); var position = $(this).offset(); $opr.css({ top:position.top+"px", left:(position.left*(1.1))+"px" }).fadeIn(100); // console.log(children.attr('class')); _this=$(this); //默认隐藏创建按钮 $(document).one("click", function(){ $opr.hide(); }); e.stopPropagation(); } }); $oprli.on("click",function (e) { var parent = _this.parent(); var children = parent.children("ul"); if ($(this).children().attr("id")==="file"){ //var childrens = _this.parent("li").children("ul>li"); oprShow(children,parent,"新建文件"); oprSpan("glyphicon-file"); } if ($(this).children().attr("id")==="folder"){ oprShow(children,parent,"新建文件夹"); oprSpan("glyphicon-folder-close"); //e.stopPropagation(); } }); } /** * 创建按钮出现 */ function oprShow(children,parent,fileName){ children.show(); var html ="<li><input class='new-li' value='"+fileName+"'/>" + "<span class='new-li-file new-li-save fa fa-save'></span>" + "<span class='new-li-file new-li-delete glyphicon glyphicon-remove pull-right'></span></li>" if (!children.attr("class")){ children = parent; html = "<ul class='menu-li'>"+html+"</ul>"; } children.append(html); } /** * 新创文件按钮操作 */ function oprSpan(fileClass){ //删除 $body.on("click",".new-li-delete",function () { $(this).parent("li").remove(); }); //保存 $body.on("click",".new-li-save",function () { //ajax请求接口,后端验证之后 var obj = inputToSpan($(this).parent("li").children("input")," glyphicon "+fileClass+" opr-span-reset"); if (obj && obj.parent("li")){ obj.parent("li").find(".new-li-file").hide() } }); } /** * input转span */ function inputToSpan($input,fileClass){ var obj; $input.replaceWith(function() { obj =$("<span class='"+$(this).attr("class")+" menu-span glyphicon "+fileClass+" '></span>"); return obj.text($(this).val()); }); console.log(obj) return obj; } /** * 初始化函数 */ function init(){ $(".parent>ul>li>ul").remove(); $.ajax({ url: '/test/array', type: 'GET', dataType: 'json', }).done(function (data) { if (data.rs) { var res = data.data; var h1 = "<li>菜单"; h1 =ul(res,h1); h1+="</li>"; $(".parent>ul").append(h1); $("ul li .ul-close1").hide(); } }).fail(function () { }); } /** * 递归菜单 * @param arry * @param h1 * @returns {*} */ var a1; var a2; var className; var childFlag = 0; var ulCloseClass = ""; function ul(arry){ if (arry.length===""){ return ""; } if (arry.length===0){ return ""; } ulCloseClass = (childFlag===0)?"":" ul-close1"; var h1="<ul class='menu-ul "+ulCloseClass+ "'>"; arry.forEach(item=>{ a1 = (item.url!==null&&item.child.length===0)?"<a href='"+item.url+"'>":""; a2 = (item.child.length===0)?"</a>":""; className = item.child.length!==0?"glyphicon glyphicon-folder-close opr-span-reset":"glyphicon glyphicon-file opr-span-reset"; h1+="<li class='menu-li'>"+a1+"<span class='menu-span "+className+"'" + "style=' background-image: url("+item.backgroundImage+"')\">"+item.name+"</span>"; if (item.child.length!==0){ childFlag = 1; var child = item.child; h1+=ul(child); childFlag =0; } h1+=(a2)+"</li>"; }) h1+="</ul>"; return h1; } </script>
复制
初始化init()和递归菜单ul()变动不大,其中,init()函数中,data数据是模拟的,当然,我自己的是从数据出查过来的,通过一些方法,将其中的子类划分给父类,也可以mybatis进行整合,这可能和sql设计数据相关,就不多说了。closeAndOpen()函数修改了一些bug和新增一些新功能,比如修复了文件点击也会变成文件夹打开的图标,文件右键也出现创建文件和文件夹的按钮。修改不够的方式是:通过参数isfile 判定是否不为文件(为文件夹)进行操作。一个变量解决两个bug。
新功能:删除和文件的添加。
首先是一个监听创建文件和文件夹的按钮 ,执行操作有:{
1.判定点击创建的是文件还是文件夹
2.进入if进行执行:{
(1)创建新的li标签
三个参数(子节点,父节点,特定的文件class名称),为什么要父子都要传入?因为我有神经病。咳咳咳。开玩笑的。因为子节点<li>可能为undefined,这时候就用到他的父标签<ul>。也可以只传一个,这个问题你自己去思考,是父节点还子节点。直接用children.parent()获取行不行?
底下就是一个节点判断
(2)文件按钮的一个删除和添加操作,这里不得不得不提得是,作为全栈的小伙伴们删除和添加必须要进行后端验证,获得验证成功的数据方可执行页面的一些相关操作,包括最后将li标签中的input转换成span
}
}
以上便是你们期待的结果。可能存在一些小bug。
打赏
创作不易,打赏鼓励(zfb)