功能,思维导图笔记
优点,样式不到200行,可自行更换风格,内容可摘取到配置文件
<!DOCTYPE html> <html lang="zh-CN"> <head> <meta charset="UTF-8"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <title>战锤40K - 思维导图</title> <style> /* --- 整体样式与背景优化 --- */ body { font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, "Helvetica Neue", Arial, sans-serif; font-size: 14px; /* 字体增大 */ line-height: 1.5; margin: 8px; background-color: #2c3e50; /* 更好看的深色背景 */ color: #ecf0f1; /* 适配深色背景的浅色文字 */ } /* --- 控制按钮样式 --- */ #controls { position: fixed; /* 固定在页面上 */ top: 10px; left: 10px; z-index: 1000; /* 确保在最上层 */ } #controls button { padding: 8px 12px; margin-right: 5px; font-size: 12px; cursor: pointer; background-color: #34495e; color: #ecf0f1; border: 1px solid #7f8c8d; border-radius: 4px; } #controls button:hover { background-color: #4a627a; } /* --- 树形图样式 --- */ #tree-container { margin-top: 50px; /* 为顶部按钮留出空间 */ } ul { padding-left: 20px; /* 缩进稍微增加 */ margin: 0; list-style: none; } li { margin: 2px 0; position: relative; } /* --- 连接线样式,适配深色背景 --- */ li::before { content: ''; position: absolute; left: -15px; top: 11px; /* 与文字中线对齐 */ width: 12px; height: 1px; border-top: 1px solid #7f8c8d; /* 更亮的线条 */ } li:last-child::after { content: ''; position: absolute; left: -15px; top: -11px; bottom: 11px; /* 到自身中线为止 */ width: 1px; border-left: 1px solid #2c3e50; /* 用背景色覆盖父级的线 */ } ul > li::after { /* 父级的垂直线 */ content: ''; position: absolute; left: -15px; top: -11px; bottom: 0; width: 1px; border-left: 1px solid #7f8c8d; /* 更亮的线条 */ } ul > li:last-child::after { display: none; } /* --- 可折叠交互样式 --- */ .toggle { cursor: pointer; user-select: none; font-weight: bold; } .toggle::before { content: '▶ '; color: #95a5a6; /* 更亮的箭头颜色 */ display: inline-block; width: 12px; } .toggle.open::before { content: '▼ '; } .collapsible { display: none; /* 默认隐藏 */ } </style> </head> <body> <!-- 控制按钮 --> <div id="controls"> <button id="expandAllBtn">展开全部</button> <button id="collapseAllBtn">折叠全部</button> </div> <!-- 树形容器 --> <div id="tree-container"> <ul id="tree"></ul> </div> <script> // --- 数据保持不变 --- const treeData = { text: "战锤40K", children: [ { text: "1. 背景设定", children: [ /* ... 数据与之前相同 ... */ ] }, { text: "2. 主要势力", children: [ /* ... 数据与之前相同 ... */ ] }, { text: "3. 游戏系列", children: [ /* ... 数据与之前相同 ... */ ] }, { text: "4. 衍生作品", children: [ /* ... 数据与之前相同 ... */ ] }, { text: "5. 世界观评价", children: [ /* ... 数据与之前相同 ... */ ] }, { text: "6. 制作公司", children: [ /* ... 数据与之前相同 ... */ ] } ] }; // 为了代码简洁,这里用注释代替完整数据,实际使用时请用上一版完整的数据填充 // 完整数据请参考上一个回答中的 treeData 对象 treeData.children = [ { text: "1. 背景设定", children: [ { text: "1.1 时代背景", children: [{ text: "第四十一个千年" }, { text: "人类帝国的黄昏" }, { text: "无尽战争" }] }, { text: "1.2 银河系", children: [{ text: "星区" }, { text: "子星区" }, { text: "行星系统" }] }, { text: "1.3 人类帝国", children: [{ text: "帝皇" }, { text: "国教" }, { text: "审判庭", children: [{ text: "异端审判庭" }, { text: "异形审判庭" }, { text: "恶魔审判庭" }] }, { text: "星际战士", children: [{ text: "原体" }, { text: "战团" }] }, { text: "帝国卫队" }, { text: "机械神教" }, { text: "海军" }] }, { text: "1.4 亚空间", children: [{ text: "混沌" }, { text: "邪神", children: [{ text: "恐虐:战争、仇恨、愤怒之神" }, { text: "奸奇:欺诈、阴谋、变化之神" }, { text: "纳垢:腐朽、疾病、绝望之神" }, { text: "色孽:欢愉、过量、奢靡之神" }] }, { text: "恶魔" }] }, { text: "1.5 灵族", children: [{ text: "灵族帝国遗迹" }, { text: "死神军" }, { text: "巫灵会" }, { text: "海盗" }] }, { text: "1.6 泰伦虫族", children: [{ text: "巢体意志" }, { text: "进化适应性" }, { text: "虫巢舰队" }] }, { text: "1.7 太空死灵", children: [{ text: "古圣的敌人" }, { text: "活体金属" }, { text: "王朝" }] }, { text: "1.8 兽人", children: [{ text: "WAAAGH!" }, { text: "兽人社会" }, { text: "科技" }] }, { text: "1.9 T'au", children: [{ text: "上上善道" }, { text: "种族联盟" }, { text: "T'au" }, { text: "克鲁特" }, { text: "vespid" }] } ] }, { text: "2. 主要势力", children: [{ text: "2.1 秩序阵营", children: [{ text: "人类帝国", children: [{ text: "星际战士" }, { text: "帝国卫队" }, { text: "机械神教" }, { text: "审判庭" }] }, { text: "T'au帝国", children: [{ text: "T'au" }, { text: "克鲁特" }, { text: "蜂鸟" }] }] }, { text: "2.2 混乱阵营", children: [{ text: "混沌星际战士", children: [{ text: "黑军团" }, { text: "千子" }, { text: "纳垢信徒" }, { text: "帝皇之子" }, { text: "钢铁勇士" }, { text: "死亡守卫" }, { text: "世界吞噬者" }] }, { text: "恶魔" }] }, { text: "2.3 异形阵营", children: [{ text: "灵族" }, { text: "兽人" }, { text: "泰伦虫族" }, { text: "太空死灵" }] }, { text: "2.4 中立阵营", children: [{ text: "灵族海盗" }, { text: "基因窃取者教派" }, { text: "哈米吉多顿兽人" }, { text: "失落与被诅咒者" }] }] }, { text: "3. 游戏系列", children: [{ text: "3.1 桌面战棋", children: [{ text: "Warhammer 40,000" }, { text: "Kill Team" }, { text: "Aeronautica Imperialis" }, { text: "Adeptus Titanicus" }] }, { text: "3.2 角色扮演", children: [{ text: "Dark Heresy" }, { text: "Rogue Trader" }, { text: "Deathwatch" }, { text: "Black Crusade" }, { text: "Only War" }] }, { text: "3.3 电子游戏", children: [{ text: "《战争黎明》系列" }, { text: "《星际战士》" }, { text: "《战争机器:竞技场》" }, { text: "《战锤40K:行商浪人》" }, { text: "《战锤40K:暗潮》" }] }] }, { text: "4. 衍生作品", children: [{ text: "4.1 小说", children: [{ text: "荷鲁斯大叛乱系列" }, { text: "Gaunt's Ghosts系列" }, { text: "Eisenhorn系列" }, { text: "The Beast Arises系列" }] }, { text: "4.2 漫画", children: [{ text: "Deff Skwadron" }, { text: "Damnation Crusade" }] }, { text: "4.3 桌面游戏", children: [{ text: "Space Hulk" }, { text: "Talisman" }] }, { text: "4.4 电影", children: [{ text: "《战锤40K:极限战士》" }] }] }, { text: "5. 世界观评价", children: [{ text: "5.1 黑暗科幻风格", children: [{ text: "反乌托邦" }, { text: "宇宙恐怖" }] }, { text: "5.2 哥特美学", children: [{ text: "建筑风格" }, { text: "艺术与设计" }] }, { text: "5.3 政治与宗教讽刺", children: [{ text: "极端主义" }, { text: "神权统治" }] }] }, { text: "6. 制作公司", children: [{ text: "6.1 Games Workshop (GW)", children: [{ text: "公司历史" }, { text: "产品线" }, { text: "Citadel Miniatures" }] }] } ]; // --- 动态生成 HTML 结构的函数 --- function createTreeNode(nodeData) { const li = document.createElement('li'); const span = document.createElement('span'); span.textContent = nodeData.text; if (nodeData.children && nodeData.children.length > 0) { span.className = 'toggle'; li.appendChild(span); const childUl = document.createElement('ul'); childUl.className = 'collapsible'; nodeData.children.forEach(child => { childUl.appendChild(createTreeNode(child)); }); li.appendChild(childUl); } else { li.appendChild(span); } return li; } // --- 初始化函数 --- function initializeTree() { const treeContainer = document.getElementById('tree'); const rootNode = createTreeNode(treeData); treeContainer.appendChild(rootNode); // 默认展开第一层级 const firstLevelNodes = treeContainer.querySelectorAll(':scope > li > ul.collapsible'); firstLevelNodes.forEach(node => { node.style.display = 'block'; node.previousElementSibling.classList.add('open'); }); // 单个节点点击事件(事件委托) treeContainer.addEventListener('click', (event) => { if (event.target.classList.contains('toggle')) { event.target.classList.toggle('open'); const content = event.target.nextElementSibling; if (content) { content.style.display = (content.style.display === 'block') ? 'none' : 'block'; } } }); } // --- 全部展开/折叠功能 --- function setupControls() { const expandAllBtn = document.getElementById('expandAllBtn'); const collapseAllBtn = document.getElementById('collapseAllBtn'); expandAllBtn.addEventListener('click', () => { document.querySelectorAll('.collapsible').forEach(el => el.style.display = 'block'); document.querySelectorAll('.toggle').forEach(el => el.classList.add('open')); }); collapseAllBtn.addEventListener('click', () => { document.querySelectorAll('.collapsible').forEach(el => el.style.display = 'none'); document.querySelectorAll('.toggle').forEach(el => el.classList.remove('open')); }); } // --- 页面加载完成后执行 --- document.addEventListener('DOMContentLoaded', () => { initializeTree(); setupControls(); }); </script> </body> </html>