feat: 手机端添加目录按钮,点击弹出章节导航弹窗

This commit is contained in:
李策 2026-03-26 17:47:26 +08:00
parent c99295ccac
commit 17b6a5d7e0

View File

@ -207,6 +207,98 @@
flex-direction: column; flex-direction: column;
} }
/* 移动端目录弹窗 */
.toc-modal {
display: none;
position: fixed;
top: 0; left: 0; right: 0; bottom: 0;
background: rgba(0,0,0,0.8);
z-index: 2000;
justify-content: center;
align-items: center;
padding: 20px;
}
.toc-modal.active { display: flex; }
.toc-content {
background: var(--bg-primary);
border-radius: 12px;
border: 1px solid var(--border-color);
width: 100%;
max-width: 400px;
max-height: 80vh;
display: flex;
flex-direction: column;
overflow: hidden;
}
.toc-header {
display: flex;
justify-content: space-between;
align-items: center;
padding: 15px 20px;
border-bottom: 1px solid var(--border-color);
}
.toc-title {
font-size: 16px;
font-weight: 600;
color: var(--text-primary);
}
.toc-close {
width: 32px; height: 32px;
border-radius: 8px;
background: var(--btn-bg);
border: 1px solid var(--border-color);
color: var(--text-primary);
cursor: pointer;
display: flex;
align-items: center;
justify-content: center;
font-size: 18px;
transition: all 0.3s ease;
}
.toc-close:hover { background: var(--btn-hover); }
.toc-list {
overflow-y: auto;
padding: 10px 20px 20px;
flex: 1;
}
.toc-item {
display: block;
padding: 12px 0;
color: var(--text-secondary);
text-decoration: none;
font-size: 14px;
border-bottom: 1px solid var(--border-color);
transition: all 0.3s ease;
line-height: 1.5;
}
.toc-item:hover { color: #667eea; }
.toc-item.current { color: #667eea; font-weight: 600; }
/* 目录按钮(仅手机端显示) */
.toc-btn {
display: none;
padding: 12px 20px;
background: var(--btn-bg);
border: 1px solid var(--border-color);
border-radius: 8px;
color: var(--text-primary);
font-family: 'Noto Sans SC', sans-serif;
font-size: 14px;
cursor: pointer;
transition: all 0.3s ease;
}
.toc-btn:hover { background: var(--btn-hover); }
.sidebar-title { .sidebar-title {
font-size: 14px; font-size: 14px;
color: var(--text-secondary); color: var(--text-secondary);
@ -262,6 +354,11 @@
@media (max-width: 1200px) { .sidebar { display: none; } } @media (max-width: 1200px) { .sidebar { display: none; } }
@media (max-width: 768px) {
.toc-btn { display: block; }
.sidebar { display: none; }
}
@media (max-width: 600px) { @media (max-width: 600px) {
.chapter-title { font-size: 24px; } .chapter-title { font-size: 24px; }
.chapter-content { font-size: 16px; } .chapter-content { font-size: 16px; }
@ -293,11 +390,23 @@
<nav class="fixed-nav"> <nav class="fixed-nav">
<div class="fixed-nav-content"> <div class="fixed-nav-content">
<a href="#" class="nav-btn" id="prevBtn">上一章</a> <a href="#" class="nav-btn" id="prevBtn">上一章</a>
<button class="toc-btn" id="tocBtn">目录</button>
<a href="chapters.html" class="nav-btn">目录</a> <a href="chapters.html" class="nav-btn">目录</a>
<a href="#" class="nav-btn" id="nextBtn">下一章</a> <a href="#" class="nav-btn" id="nextBtn">下一章</a>
</div> </div>
</nav> </nav>
<!-- 移动端目录弹窗 -->
<div class="toc-modal" id="tocModal">
<div class="toc-content">
<div class="toc-header">
<span class="toc-title">章节导航</span>
<button class="toc-close" id="tocClose">×</button>
</div>
<div class="toc-list" id="tocList"></div>
</div>
</div>
<!-- 右侧滚动按钮 --> <!-- 右侧滚动按钮 -->
<div class="scroll-buttons"> <div class="scroll-buttons">
<button class="scroll-btn" id="scrollTop"></button> <button class="scroll-btn" id="scrollTop"></button>
@ -356,6 +465,8 @@
// 更新侧边栏高亮 // 更新侧边栏高亮
updateSidebarHighlight(); updateSidebarHighlight();
// 更新移动端目录高亮
updateMobileTOCHighlight();
// 记录阅读进度 // 记录阅读进度
let readChapters = JSON.parse(localStorage.getItem('readChapters') || '[]'); let readChapters = JSON.parse(localStorage.getItem('readChapters') || '[]');
@ -451,12 +562,64 @@
window.scrollTo({ top: document.body.scrollHeight, behavior: 'smooth' }); window.scrollTo({ top: document.body.scrollHeight, behavior: 'smooth' });
}); });
// 渲染移动端目录
function renderMobileTOC() {
const data = window.chaptersData || chaptersData;
const tocList = document.getElementById('tocList');
let html = '';
data.forEach(ch => {
const isCurrent = ch.id === currentChapter ? 'current' : '';
html += `<a href="?id=${ch.id}" class="toc-item ${isCurrent}" data-id="${ch.id}">第${ch.id}章:${ch.title}</a>`;
});
tocList.innerHTML = html;
}
// 更新移动端目录高亮
function updateMobileTOCHighlight() {
document.querySelectorAll('.toc-item').forEach(item => {
item.classList.remove('current');
if (parseInt(item.dataset.id) === currentChapter) {
item.classList.add('current');
}
});
}
// 目录弹窗控制
const tocModal = document.getElementById('tocModal');
const tocBtn = document.getElementById('tocBtn');
const tocClose = document.getElementById('tocClose');
tocBtn.addEventListener('click', () => {
renderMobileTOC();
tocModal.classList.add('active');
});
tocClose.addEventListener('click', () => {
tocModal.classList.remove('active');
});
tocModal.addEventListener('click', (e) => {
if (e.target === tocModal) {
tocModal.classList.remove('active');
}
});
// 点击目录项后关闭弹窗
document.getElementById('tocList').addEventListener('click', (e) => {
if (e.target.classList.contains('toc-item')) {
tocModal.classList.remove('active');
}
});
// 初始化 - 等待app.js加载章节数据 // 初始化 - 等待app.js加载章节数据
document.addEventListener('DOMContentLoaded', async function() { document.addEventListener('DOMContentLoaded', async function() {
// 等待章节数据加载完成 // 等待章节数据加载完成
await loadChaptersData(); await loadChaptersData();
// 渲染侧边栏 // 渲染侧边栏
renderReaderSidebar(); renderReaderSidebar();
// 渲染移动端目录
renderMobileTOC();
// 加载当前章节 // 加载当前章节
loadChapterContent(currentChapter); loadChapterContent(currentChapter);
}); });