推荐答案
// www.javascriptcn.com code example
class TreeNode {
constructor(value) {
this.value = value;
this.children = [];
this.isExpanded = false;
this.isSelected = false;
}
toggleExpand() {
this.isExpanded = !this.isExpanded;
}
toggleSelect() {
this.isSelected = !this.isSelected;
}
addChild(child) {
this.children.push(child);
}
}
class Tree {
constructor(rootValue) {
this.root = new TreeNode(rootValue);
}
render() {
const renderNode = (node) => {
const nodeElement = document.createElement('div');
nodeElement.textContent = node.value;
nodeElement.style.marginLeft = '20px';
nodeElement.style.cursor = 'pointer';
if (node.isSelected) {
nodeElement.style.backgroundColor = 'lightblue';
}
nodeElement.addEventListener('click', (e) => {
e.stopPropagation();
node.toggleSelect();
this.render();
});
if (node.children.length > 0) {
const toggleButton = document.createElement('button');
toggleButton.textContent = node.isExpanded ? '-' : '+';
toggleButton.addEventListener('click', (e) => {
e.stopPropagation();
node.toggleExpand();
this.render();
});
nodeElement.prepend(toggleButton);
}
if (node.isExpanded && node.children.length > 0) {
node.children.forEach(child => {
nodeElement.appendChild(renderNode(child));
});
}
return nodeElement;
};
const treeContainer = document.getElementById('tree');
treeContainer.innerHTML = '';
treeContainer.appendChild(renderNode(this.root));
}
}
// 使用示例
const tree = new Tree('Root');
const child1 = new TreeNode('Child 1');
const child2 = new TreeNode('Child 2');
const grandChild1 = new TreeNode('Grandchild 1');
const grandChild2 = new TreeNode('Grandchild 2');
child1.addChild(grandChild1);
child2.addChild(grandChild2);
tree.root.addChild(child1);
tree.root.addChild(child2);
tree.render();本题详细解读
1. TreeNode 类
- value: 存储节点的值。
- children: 存储子节点的数组。
- isExpanded: 控制节点是否展开。
- isSelected: 控制节点是否被选中。
- toggleExpand(): 切换节点的展开状态。
- toggleSelect(): 切换节点的选中状态。
- addChild(child): 添加子节点。
2. Tree 类
- root: 树的根节点。
- render(): 渲染树结构。
- renderNode(node): 递归渲染每个节点。
- 创建节点元素并设置样式。
- 如果节点被选中,设置背景色。
- 添加点击事件以切换选中状态。
- 如果有子节点,添加展开/折叠按钮。
- 如果节点展开,递归渲染子节点。
3. 使用示例
- 创建一个根节点为 "Root" 的树。
- 添加两个子节点 "Child 1" 和 "Child 2"。
- 为每个子节点添加一个孙子节点。
- 调用
render() 方法渲染树结构。
4. 关键点
- 递归渲染: 使用递归来渲染树的每个节点。
- 事件处理: 通过事件监听器处理节点的展开、折叠和选中操作。
- 动态更新: 每次操作后重新渲染树以反映状态变化。
5. 扩展性
- 可以进一步扩展树的功能,如支持多选、拖拽、异步加载子节点等。
- 可以通过 CSS 进一步美化树的样式。