最近的项目不允许使用框架,遇到自定义树形表格的页面功能。
为了赶时间,就想找现成的,百度找到“基于JQuery TreeTable实现的属性表单”,结果进去一看,都是一毛一样的,没有实现方式的代码,深深怀疑是不是就抄个代码根本没有自己测试过,也浪费了不少时间。
之后仔细一想,其实实现并不困了,不一定非要找现成的。按照自己的思路,做出结果如下,如有bug欢迎指正。
思路
我想的很简单,
- 一个箭头显示打开、收起的样式;
- 在箭头上加入toggle()方法控制一级菜单下的所有子菜单的样式,通过display样式控制子菜单隐藏/显示,从而实现树型菜单打开、收起的效果;
- 在子级上添加自定义属性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"
}
]
}
]
}