基于JQuery的自定义树形菜单表格,实现展开、收起效果

最近的项目不允许使用框架,遇到自定义树形表格的页面功能。
为了赶时间,就想找现成的,百度找到“基于JQuery TreeTable实现的属性表单”,结果进去一看,都是一毛一样的,没有实现方式的代码,深深怀疑是不是就抄个代码根本没有自己测试过,也浪费了不少时间。
在这里插入图片描述

之后仔细一想,其实实现并不困了,不一定非要找现成的。按照自己的思路,做出结果如下,如有bug欢迎指正。

思路

我想的很简单,

  1. 一个箭头显示打开、收起的样式;
  2. 在箭头上加入toggle()方法控制一级菜单下的所有子菜单的样式,通过display样式控制子菜单隐藏/显示,从而实现树型菜单打开、收起的效果;
  3. 在子级上添加自定义属性open来标识当前子级是隐藏还是展开,通过pid来关联父级。

效果

在这里插入图片描述

引用

(可能还有需要引入的,如果有报错根据提示添加)

<script th:src="@{/plugins/jquery/jquery.min.js}"></script>

HTML

<div class="card">
    <table id="treeTable" class="table">
        <thead>
        <tr role="row">
            <th>分类名称</th>
            <th>分类级别</th>
            <th>操作</th>
        </tr>
        </thead>
        <tbody id="class-info">
        </tbody>
    </table>
</div>

JS

$(function () {
	loadTreeTable();
})

// 加载table数据
function loadTreeTable() {
    commonGet("/admin/serverClass/list", {}).then(res => {
        if (res.code === '200') {
            var list = res.data;
            if (list !== null) {
                var html = '';
                for (var i = 0; i < list.length; i++) {
                    var listChild = list[i].childrenServiceClasses;
                    // 如果有子元素,则设置toggle()
                    if (listChild !== null && listChild.length > 0) {
                        html += '<tr id="' + list[i].id + '" pid="0">\n' +
                            '    <td><span class="switch-close" οnclick="toggle(this)"></span><span class="folder">' + list[i].className + '</span></td>\n' +
                            '    <td>' + list[i].level + '</td>\n' +
                            '    <td>操作</td>\n' +
                            '</tr>';
                    } else {
                        html += '<tr id="' + list[i].id + '" pid="0">\n' +
                            '    <td>' + list[i].className + '</td>\n' +
                            '    <td>' + list[i].level + '</td>\n' +
                            '    <td>操作</td>\n' +
                            '</tr>';
                    }
                    // 所有子元素添加pid和自定义的open属性
                    if (listChild !== null && listChild.length > 0) {
                        for (var j = 0; j < listChild.length; j++) {
                            html += '<tr open="true" id="' + listChild[j].id + '" pid="' + listChild[j].parentId + '">\n' +
                                '    <td style="padding-left: 50px;">' + listChild[j].className + '</td>\n' +
                                '    <td>' + listChild[j].level + '</td>\n' +
                                '    <td>操作</td>\n' +
                                '</tr>';
                        }
                    }
                }
                $("#class-info").append(html);
            }
        }
    })
}

//处理展开和收起
function toggle(eve) {
    var par = eve.parentNode.parentNode; // 当前的tr
    var parentId = par.getAttribute("id"); //父级id
    var bool = par.nextSibling.getAttribute("open"); //通过open属性定义当前tr是否展开
    if(bool) {
        eve.className='switch-open';
        $("tr[pid$="+parentId+"]").css("display","none"); // 所有pid=parentId的tr元素隐藏
        $("tr[pid$="+parentId+"]").attr("open", false); // 标记这些tr元素open属性,再次点击就会实现相反操作
    } else {
        eve.className='switch-close';
        $("tr[pid$="+parentId+"]").removeAttr("style");
        $("tr[pid$="+parentId+"]").attr("open", true);
    }
}

CSS

/* 可展开*/
.switch-open {
    border:6px solid transparent;
    display:inline-block;
    width:0px;
    height:0px;
    border-top-color: black;
    margin-right: 5px;
}
/* 展开完毕*/
.switch-close {
    border:6px solid transparent;
    display:inline-block;
    width:0px;
    height:0px;
    border-left-color: black;
    margin-bottom: 2px;
    margin-right: 5px;
}

后端接口返回值示例

{
    "code": "200",
    "msg": "操作成功",
    "data": [
        {
            "id": "1",
            "level": 1,
            "className": "知识产权服务",
            "parentId": null,
            "childrenServiceClasses": [
                {
                    "id": "11",
                    "level": 2,
                    "className": "知识产权分析评议",
                    "parentId": "1"
                },
                {
                    "id": "12",
                    "level": 2,
                    "className": "专利维权",
                    "parentId": "1"
                },
                {
                    "id": "13",
                    "level": 2,
                    "className": "价值评估",
                    "parentId": "1"
                },
                {
                    "id": "34",
                    "level": 2,
                    "className": "专利质押保险",
                    "parentId": "1"
                }
            ]
        },
        {
            "id": "5",
            "level": 1,
            "className": "创新创业服务",
            "parentId": null,
            "childrenServiceClasses": [
                {
                    "id": "25",
                    "level": 2,
                    "className": "企业创新能力诊断",
                    "parentId": "5"
                },
                {
                    "id": "31",
                    "level": 2,
                    "className": "创业导师服务",
                    "parentId": "5"
                }
            ]
        },
        {
            "id": "6",
            "level": 1,
            "className": "科技金融服务",
            "parentId": null,
            "childrenServiceClasses": [
                {
                    "id": "28",
                    "level": 2,
                    "className": "科创板培育",
                    "parentId": "6"
                },
                {
                    "id": "33",
                    "level": 2,
                    "className": "高企财税规划",
                    "parentId": "6"
                }
            ]
        }
    ]
}
  • 0
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 2
    评论
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值