在Discuz的帖子内容页添加动态大纲目录,可以按照以下步骤实现:
一、模板文件修改(viewthread.htm)
<!-- 在右侧DIY区域添加目录容器(一般放在类似位置) -->
<div class="module cl xl xl1" id="thread_toc_container">
<div class="thread-toc-title"><h3>帖子导航目录</h3></div>
<div id="thread_toc"></div>
</div>
<!-- 在页面底部添加脚本 -->
<script>
document.addEventListener('DOMContentLoaded', function() {
// 获取帖子正文容器(根据实际模板结构调整选择器)
const postContent = document.querySelector('.t_fsz') || document.querySelector('.postmessage');
// 获取所有标题元素
const headings = postContent.querySelectorAll('h2, h3, h4, h5, h6');
// 创建目录容器
const tocContainer = document.getElementById('thread_toc');
let tocHTML = '<ul class="toc-list">';
headings.forEach((heading, index) => {
// 如果标题没有ID则自动生成
if (!heading.id) {
heading.id = 'heading_' + index;
}
// 构建目录项
tocHTML += `
<li class="toc-item toc-${heading.tagName.toLowerCase()}">
<a href="#${heading.id}" onclick="smoothScroll(event, '${heading.id}')">
${heading.textContent}
</a>
</li>
`;
});
tocHTML += '</ul>';
tocContainer.innerHTML = tocHTML;
// 自动隐藏空目录
if (headings.length === 0) {
document.getElementById('thread_toc_container').style.display = 'none';
}
});
// 平滑滚动函数
function smoothScroll(event, targetId) {
event.preventDefault();
const target = document.getElementById(targetId);
if (target) {
window.scrollTo({
top: target.offsetTop - 60, // 留出顶部导航栏空间
behavior: 'smooth'
});
history.replaceState(null, null, '#' + targetId); // 更新URL哈希
}
}
</script>
二、CSS样式添加(common.css)
/* 目录容器样式 */
#thread_toc_container {
position: sticky;
top: 80px;
background: #f9f9f9;
border: 1px solid #eee;
padding: 15px;
max-height: 80vh;
overflow-y: auto;
z-index: 999;
}
/* 目录项样式 */
.toc-list {
list-style: none;
margin: 0;
padding: 0;
}
.toc-item {
margin: 5px 0;
line-height: 1.6;
}
.toc-item a {
color: #666;
text-decoration: none;
transition: color 0.3s;
}
.toc-item a:hover {
color: #36c;
}
.toc-h2 { padding-left: 0; }
.toc-h3 { padding-left: 15px; }
.toc-h4 { padding-left: 30px; }
.toc-h5 { padding-left: 45px; }
.toc-h6 { padding-left: 60px; }
/* 手机端隐藏 */
@media (max-width: 768px) {
#thread_toc_container {
display: none;
}
}
三、增强功能(可选)
在脚本后追加以下代码实现更多功能:
// 自动高亮当前阅读位置
window.addEventListener('scroll', function() {
const headings = document.querySelectorAll('[id^="heading_"]');
let currentActive = null;
headings.forEach(heading => {
const rect = heading.getBoundingClientRect();
if (rect.top < window.innerHeight * 0.2) {
currentActive = heading.id;
}
});
document.querySelectorAll('.toc-item a').forEach(link => {
link.style.fontWeight = link.hash === `#${currentActive}` ? 'bold' : 'normal';
link.style.color = link.hash === `#${currentActive}` ? '#36c' : '#666';
});
});
// 自动折叠长目录
const MAX_VISIBLE_ITEMS = 20;
if (document.querySelectorAll('.toc-item').length > MAX_VISIBLE_ITEMS) {
const toggleBtn = document.createElement('button');
toggleBtn.innerHTML = '展开完整目录 ▼';
toggleBtn.style.cssText = 'background:none; border:0; color:#369; cursor:pointer; padding:5px 0;';
toggleBtn.onclick = () => {
tocContainer.classList.toggle('expanded');
toggleBtn.innerHTML = tocContainer.classList.contains('expanded') ? '收起目录 ▲' : '展开完整目录 ▼';
};
tocContainer.parentNode.insertBefore(toggleBtn, tocContainer);
tocContainer.style.maxHeight = '400px';
tocContainer.style.overflowY = 'hidden';
}
四、实现效果说明
- 动态生成:自动检测帖子内容中的h2-h6标题
- 层级缩进:通过CSS实现多级标题缩进显示
- 智能定位:
- 目录容器采用sticky定位始终可见
- 点击目录项平滑滚动到对应位置
- 自动更新URL哈希
- 阅读进度感知:
- 滚动时自动高亮当前阅读的章节
- 超过20个目录项时自动折叠
- 响应式设计:
五、注意事项
- 如果帖子内容通过AJAX加载,需要将脚本放在加载完成后执行
- 部分模板可能需要调整选择器(
.t_fsz 或.postmessage )
- 如果使用分页显示,需要合并多页内容处理
- 可通过修改CSS变量调整颜色方案:
:root {
--toc-primary-color: #36c;
--toc-bg-color: #f9f9f9;
--toc-border-color: #eee;
}
|