产品需求,10W条数据渲染一个树形组件,使用市场插件,会样式丢失,无奈只能自己写一个。感觉不是在造树,而是在造森林!吐槽产品经理
- 问题:
- 数据过多样式丢失
- 递归过多,Jquery会报错
- 解决办法
- 使用行内样式
- 点击节点时请求加载数据,渲染子节点
<html>
<head>
</head>
<body>
<div>
<div><button onclick="getCheckedNodes()">查看选中</button></div>
<hr />
<ul id="treeDiv" style="list-style: none;">
</ul>
</div>
<script src="https://cdn.bootcdn.net/ajax/libs/jquery/3.5.1/jquery.js"></script>
<script>
let treeDataInfos = [{
id: 1,
title: 'AAA',
children: [{
id: 12,
title: 'AAA',
parentIds: "1",
},
{
id: 13,
title: 'AAA',
parentIds: "1",
},
{
id: 14,
title: 'AAA',
parentIds: "1",
},
{
id: 15,
title: 'AAA',
parentIds: "1",
}
]
},
{
id: 2,
title: 'AAA'
},
{
id: 3,
title: 'AAA',
children: [{
id: 31,
title: 'AAA',
parentIds: "3",
},
{
id: 32,
title: 'AAA',
parentIds: "3",
},
{
id: 33,
title: 'AAA',
parentIds: "3",
},
{
id: 34,
title: 'AAA',
parentIds: "3",
children: [{
id: 341,
title: 'AAA',
parentIds: "3,34",
},
{
id: 342,
title: 'AAA',
parentIds: "3,34",
},
{
id: 343,
title: 'AAA',
parentIds: "3,34",
},
{
id: 344,
title: 'AAA',
parentIds: "3,34",
}
]
}
]
},
]
//默认是否展开树节点
let childNodeToggle = 'show'; //show|none
$(document).ready(function () {
// initTree();
let treeHtmlContent = createTreeNode(treeDataInfos);
//渲染树
$("#treeDiv").empty().html(treeHtmlContent.join(""));
self.treeEvents();
});
function initTree() {
let self = this;
$.ajax({
url: 'http://localhost:9090/tree',
type: 'GET', // 默认为GET
data: {
},
timeout: 50000, // 超时时间
// beforeSend:function(xhr){
// console.log(xhr)
// console.log('发送前')
// },
success: function (result) {
let treeHtmlContent = createTreeNode(result);
//渲染树
$("#treeDiv").empty().html(treeHtmlContent.join(""));
self.treeEvents();
},
error: function (xhr, textStatus) {
console.log('错误')
console.log(xhr)
console.log(textStatus)
}
})
}
function treeEvents() {
//节点收缩方法
$(".parentNode").each(function () {
$(this).click(function () {
let id = $(this).attr("node");
let ischildren = $(this).attr("ischildren");
if (ischildren) {
$("#childrenNode" + id).fadeToggle(500);
}
});
});
//复选框改变
$(".parentNodeCheckbox").change(function () {
let id = $(this).attr("node");
let parentIds = $(this).attr("parentnodes");
let checkedStatus = $(this)[0].checked;
//如果有子节点全部变更状态
$("#childrenNode" + id + " .parentNodeCheckbox").prop("checked", checkedStatus);
//如果有父节点,变更父节点状态
if (parentIds) {
//反向依次选中
let parentIdsArray = parentIds.split(",").reverse();
for (const parentId of parentIdsArray) {
//如果状态是选中,判断父节点下是否有有未选中的,若有则不处理,无则选中
if (checkedStatus) {
if (!getIsNotCheckedNode(parentId)) {
$("#parentNodeCheckbox" + parentId).prop("checked", true);
}
} else {
//依次变更父节点状态为未选中
$("#parentNodeCheckbox" + parentId).prop("checked", false);
}
}
}
});
}
//判断父节点下是否全部选中
function getIsNotCheckedNode(id) {
let isNotCheckedNode = false;
let childrenNodes = $("#childrenNode" + id + " .parentNodeCheckbox");
for (const childrenContent of childrenNodes) {
if (!$(childrenContent)[0].checked) {
isNotCheckedNode = true;
break;
}
}
return isNotCheckedNode;
}
//渲染树节点,递归思想
function createTreeNode(contents) {
let treeHtml = [];
for (const content of contents) {
treeHtml.push('<li style="list-style: none;">');
let isChildren = false;
if (content.children) {
isChildren = true;
treeHtml.push('<span style="width: 10px;font-size: x-large;color: #0488f1;">+</span>');
} else {
treeHtml.push('<span style="width: 10px;font-size: x-large;color: #E91E63;">- </span>');
}
//复选框
treeHtml.push('<input type="checkbox" class="parentNodeCheckbox" node="' + content.id +
'" parentnodes="' + content.parentIds + '" id="parentNodeCheckbox' + content.id + '"/>');
//title
treeHtml.push('<span class="parentNode" style="cursor:pointer;" ischildren="' + isChildren + '" node="' + content.id + '" >' +
content.title + '-' + content.id + '</span>');
//子节点
if (isChildren) {
treeHtml.push('<ul class="childrenNode" node="' + content.id + '" id="childrenNode' + content.id +
'" style="list-style: none;display:' + childNodeToggle + '">');
treeHtml = treeHtml.concat(createTreeNode(content.children));
treeHtml.push('</ul>');
}
treeHtml.push('</li>');
};
return treeHtml;
}
//获取选中的节点
function getCheckedNodes() {
let checkedNodes = [];
$(".parentNodeCheckbox").each(function () {
let checkedStatus = $(this)[0].checked;
if (checkedStatus) {
let id = $(this).attr("node");
checkedNodes.push(id);
}
})
console.log(checkedNodes);
}
</script>
</body>
</html>