feat: 手机端添加目录按钮,点击弹出章节导航弹窗
This commit is contained in:
parent
c99295ccac
commit
17b6a5d7e0
@ -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);
|
||||||
});
|
});
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user