前言
看到许多伙伴们对这个功能效果挺感兴趣的,鄙人捂着颓废的肝,给你们补上。
效果
请移步到上一篇: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)