From d74328959e78044a3b3b5c4d71a9959f7ff510cf Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E5=B0=8F=E8=99=BE=E7=B1=B3?= Date: Fri, 27 Mar 2026 16:02:13 +0800 Subject: [PATCH] Disable browser cache: Add no-cache headers to HTML and fetch requests --- alacarte-novel-website/chapters.html | 285 ++--- alacarte-novel-website/index.html | 463 ++++---- alacarte-novel-website/js/app.js | 1576 +++++++++++++------------- alacarte-novel-website/template.html | 897 +++++++-------- 4 files changed, 1621 insertions(+), 1600 deletions(-) diff --git a/alacarte-novel-website/chapters.html b/alacarte-novel-website/chapters.html index 1388552..2ede291 100644 --- a/alacarte-novel-website/chapters.html +++ b/alacarte-novel-website/chapters.html @@ -1,141 +1,144 @@ - - - - - - 章节目录 - 阿拉德:剑之回响 - - - - - - - - - - -
-
-
-
-
-
-
-
-

阿拉德:剑之回响

-

39 章 · 连载中

-
-
-
-
-
-
- 阅读进度 0% -
-
-
- - -
-
-
-
- - - -
- -
- -
- -
- -
- -
- 1 - / 1 -
- -
-
-
- - -
- -
- - - - - - - - + + + + + + + + + 章节目录 - 阿拉德:剑之回响 + + + + + + + + + + +
+
+
+
+
+
+
+
+

阿拉德:剑之回响

+

39 章 · 连载中

+
+
+
+
+
+
+ 阅读进度 0% +
+
+
+ + +
+
+
+
+ + + +
+ +
+ +
+ +
+ +
+ +
+ 1 + / 1 +
+ +
+
+
+ + +
+ +
+ + + + + + + + diff --git a/alacarte-novel-website/index.html b/alacarte-novel-website/index.html index 581cc5d..960cc71 100644 --- a/alacarte-novel-website/index.html +++ b/alacarte-novel-website/index.html @@ -1,230 +1,233 @@ - - - - - - 阿拉德:剑之回响 - 沉浸式阅读体验 - - - - - - - - - - -
-
-
-
-
-
-
-
-
-
-

阿拉德

-

剑之回响

-
-
作者:李策
-
-
-
-
-
-
🔥 热门连载
-

阿拉德:剑之回响

-

DNF同人 · 热血冒险 · 剑魂传说

-

- 跟随林克的脚步,从洛兰小村庄出发,一路成长为剑魂大师。
- 格兰之森的危机、天空之城的秘密、使徒的阴谋……
- 一段波澜壮阔的冒险传奇正在展开! -

-
-
- 14 - 已更新章节 -
-
- 50k+ - 总字数 -
-
- ⭐⭐⭐⭐⭐ - 读者评分 -
-
- -
-
-
- - -
-
-
-

- 📖 - 最新章节 -

- - 查看全部 - - - - -
-
- -
-
-
- - -
-
-
-
-

故事简介

-
-

🎮 基于DNF60版本经典地图

-

严格按照DNF 60版本地图等级推进,从洛兰到格兰之森,从天空之城到天帷巨兽,带你重温经典游戏场景,体验原汁原味的阿拉德大陆。

-
-
-

⚔️ 剑魂的成长之路

-

主角林克从鬼剑士成长为剑魂,掌握武器大师特性,灵活切换五种武器应对不同敌人。太刀、巨剑、短剑、钝器、光剑——在战斗中体验策略与技巧的完美结合。

-
-
-

🔥 热血冒险与深度剧情

-

不只是打怪升级,更是一段关于成长、友情与守护的传奇。赛丽亚的身世之谜、GSD的往事、天空之城的秘密……层层递进的剧情让你欲罢不能。

-
-
-
-
-
- 🌲 - 洛兰 -
-
- 🏰 - 赫顿玛尔 -
-
- ☁️ - 天空之城 -
-
- 🐋 - 天帷巨兽 -
-
-
-
-
-
-
- - -
-
-

- 👥 - 主要角色 -

-
-
-
-
- 🗡️ -
-

林克

-

主角 · 剑魂

-

从虚祖出发的鬼剑士,Lv.50剑魂,追求极致剑术,掌握五种武器切换。

-
-
-
-
- -
-

赛丽亚

-

正宫 · 元素师

-

精灵族最后的血脉,林克的正宫女友,温柔善良,与林克在艾尔文防线相遇。

-
-
-
-
- 📖 -
-

奥菲利亚

-

侧室 · GBL教

-

GBL教幸存者,天帷巨兽篇加入后宫,与赛丽亚姐妹相称,共同侍奉林克。

-
-
-
-
- 🔮 -
-

莎兰

-

暧昧 · 大魔导师

-

西海岸魔法师公会会长,与林克暧昧互动,暗精灵委托篇的重要角色。

-
-
-
-
- - - - - - - + + + + + + + + + 阿拉德:剑之回响 - 沉浸式阅读体验 + + + + + + + + + + +
+
+
+
+
+
+
+
+
+
+

阿拉德

+

剑之回响

+
+
作者:李策
+
+
+
+
+
+
🔥 热门连载
+

阿拉德:剑之回响

+

DNF同人 · 热血冒险 · 剑魂传说

+

+ 跟随林克的脚步,从洛兰小村庄出发,一路成长为剑魂大师。
+ 格兰之森的危机、天空之城的秘密、使徒的阴谋……
+ 一段波澜壮阔的冒险传奇正在展开! +

+
+
+ 14 + 已更新章节 +
+
+ 50k+ + 总字数 +
+
+ ⭐⭐⭐⭐⭐ + 读者评分 +
+
+ +
+
+
+ + +
+
+
+

+ 📖 + 最新章节 +

+ + 查看全部 + + + + +
+
+ +
+
+
+ + +
+
+
+
+

故事简介

+
+

🎮 基于DNF60版本经典地图

+

严格按照DNF 60版本地图等级推进,从洛兰到格兰之森,从天空之城到天帷巨兽,带你重温经典游戏场景,体验原汁原味的阿拉德大陆。

+
+
+

⚔️ 剑魂的成长之路

+

主角林克从鬼剑士成长为剑魂,掌握武器大师特性,灵活切换五种武器应对不同敌人。太刀、巨剑、短剑、钝器、光剑——在战斗中体验策略与技巧的完美结合。

+
+
+

🔥 热血冒险与深度剧情

+

不只是打怪升级,更是一段关于成长、友情与守护的传奇。赛丽亚的身世之谜、GSD的往事、天空之城的秘密……层层递进的剧情让你欲罢不能。

+
+
+
+
+
+ 🌲 + 洛兰 +
+
+ 🏰 + 赫顿玛尔 +
+
+ ☁️ + 天空之城 +
+
+ 🐋 + 天帷巨兽 +
+
+
+
+
+
+
+ + +
+
+

+ 👥 + 主要角色 +

+
+
+
+
+ 🗡️ +
+

林克

+

主角 · 剑魂

+

从虚祖出发的鬼剑士,Lv.50剑魂,追求极致剑术,掌握五种武器切换。

+
+
+
+
+ +
+

赛丽亚

+

正宫 · 元素师

+

精灵族最后的血脉,林克的正宫女友,温柔善良,与林克在艾尔文防线相遇。

+
+
+
+
+ 📖 +
+

奥菲利亚

+

侧室 · GBL教

+

GBL教幸存者,天帷巨兽篇加入后宫,与赛丽亚姐妹相称,共同侍奉林克。

+
+
+
+
+ 🔮 +
+

莎兰

+

暧昧 · 大魔导师

+

西海岸魔法师公会会长,与林克暧昧互动,暗精灵委托篇的重要角色。

+
+
+
+
+ + + + + + + diff --git a/alacarte-novel-website/js/app.js b/alacarte-novel-website/js/app.js index 4a506be..58b5336 100644 --- a/alacarte-novel-website/js/app.js +++ b/alacarte-novel-website/js/app.js @@ -1,782 +1,794 @@ -// ==================== 章节数据管理 ==================== -// 自动从 data/chapter-*.json 文件加载章节数据 -let chaptersData = []; -let isDataLoaded = false; - -// 加载所有章节数据 -async function loadChaptersData() { - if (isDataLoaded) return chaptersData; - - const chapters = []; - let chapterNum = 1; - - // 循环加载章节,直到找不到文件 - while (true) { - try { - // 格式化章节号(带前导零) - const chapterId = chapterNum.toString().padStart(2, '0'); - const response = await fetch(`data/chapter-${chapterId}.json`); - - if (!response.ok) { - // 尝试不带前导零的格式 - const response2 = await fetch(`data/chapter-${chapterNum}.json`); - if (!response2.ok) break; - const data = await response2.json(); - chapters.push(normalizeChapterData(data, chapterNum)); - } else { - const data = await response.json(); - chapters.push(normalizeChapterData(data, chapterNum)); - } - - chapterNum++; - } catch (error) { - // 没有更多章节了 - break; - } - } - - chaptersData = chapters; - isDataLoaded = true; - - // 将数据挂载到 window 对象,供其他函数使用 - window.chaptersData = chaptersData; - - return chaptersData; -} - -// 标准化章节数据 -function normalizeChapterData(data, defaultId) { - // 从内容中提取描述(前100个字符) - const extractDesc = (content) => { - if (!content) return ''; - // 去除换行和多余空格,取前100字符 - const cleanContent = content.replace(/\n/g, ' ').replace(/\s+/g, ' ').trim(); - return cleanContent.substring(0, 100) + (cleanContent.length > 100 ? '...' : ''); - }; - - return { - id: data.id || defaultId, - title: data.title || `第${defaultId}章`, - subtitle: data.subtitle || '', - desc: data.desc || extractDesc(data.content), - content: data.content || '', - status: data.status || '已完结', - date: data.date || '2026-03-26' - }; -} - -// ==================== DOM加载完成后初始化 ==================== -document.addEventListener('DOMContentLoaded', async function() { - // 先加载章节数据 - await loadChaptersData(); - - initTheme(); - initNavigation(); - initParticles(); - - // 根据页面类型初始化不同功能 - const currentPage = window.location.pathname.split('/').pop() || 'index.html'; - - if (currentPage === 'index.html' || currentPage === '') { - renderLatestChapters(); - } else if (currentPage === 'chapters.html') { - renderChaptersList(); - setupFilters(); - setupSearch(); - updateReadingProgress(); - } else if (currentPage === 'reader.html') { - initReader(); - } else if (currentPage.startsWith('chapter-')) { - // 独立章节页面初始化 - initChapterReader(); - } - - // 初始化回到顶部按钮 - initScrollTop(); - - // 初始化阅读器设置 - initReaderSettings(); -}); - -// ==================== 主题切换 ==================== -function initTheme() { - const themeToggle = document.getElementById('themeToggle'); - if (!themeToggle) return; - - // 检查本地存储的主题 - const savedTheme = localStorage.getItem('theme') || 'dark'; - document.documentElement.setAttribute('data-theme', savedTheme); - updateThemeIcon(savedTheme); - - themeToggle.addEventListener('click', () => { - const currentTheme = document.documentElement.getAttribute('data-theme'); - const newTheme = currentTheme === 'dark' ? 'light' : 'dark'; - - document.documentElement.setAttribute('data-theme', newTheme); - localStorage.setItem('theme', newTheme); - updateThemeIcon(newTheme); - }); -} - -function updateThemeIcon(theme) { - const themeToggle = document.getElementById('themeToggle'); - if (!themeToggle) return; - - const icon = themeToggle.querySelector('.theme-icon'); - if (icon) { - icon.textContent = theme === 'dark' ? '🌙' : '☀️'; - } -} - -// ==================== 导航栏 ==================== -function initNavigation() { - const menuToggle = document.getElementById('menuToggle'); - const navLinks = document.querySelector('.nav-links'); - - if (menuToggle && navLinks) { - menuToggle.addEventListener('click', () => { - navLinks.classList.toggle('active'); - menuToggle.classList.toggle('active'); - }); - } - - // 导航栏滚动效果 - let lastScroll = 0; - const navbar = document.querySelector('.navbar'); - - if (navbar) { - window.addEventListener('scroll', () => { - const currentScroll = window.pageYOffset; - - if (currentScroll > 100) { - navbar.style.background = 'rgba(15, 15, 26, 0.95)'; - } else { - navbar.style.background = 'rgba(15, 15, 26, 0.8)'; - } - - lastScroll = currentScroll; - }); - } -} - -// ==================== 粒子效果 ==================== -function initParticles() { - const particlesContainer = document.getElementById('particles'); - if (!particlesContainer) return; - - // 创建粒子 - for (let i = 0; i < 30; i++) { - const particle = document.createElement('div'); - particle.className = 'particle'; - particle.style.cssText = ` - position: absolute; - width: ${Math.random() * 4 + 2}px; - height: ${Math.random() * 4 + 2}px; - background: rgba(99, 102, 241, ${Math.random() * 0.3 + 0.1}); - border-radius: 50%; - left: ${Math.random() * 100}%; - top: ${Math.random() * 100}%; - animation: particleFloat ${Math.random() * 10 + 10}s ease-in-out infinite; - animation-delay: ${Math.random() * 5}s; - `; - particlesContainer.appendChild(particle); - } -} - -// ==================== 首页最新章节 ==================== -function renderLatestChapters() { - const container = document.getElementById('latestChapters'); - if (!container) return; - - // 获取最新的6章 - const latestChapters = chaptersData.slice(-6).reverse(); - - container.innerHTML = latestChapters.map(chapter => ` - -
${chapter.id}
-
-

${chapter.title}

-

${chapter.desc}

-
- ${chapter.date} - ${chapter.status} -
-
-
- `).join(''); -} - -// ==================== 章节列表页 ==================== -function renderChaptersList() { - const container = document.getElementById('chaptersList'); - if (!container) return; - - // 使用加载的章节数据 - const data = window.chaptersData || chaptersData; - - container.innerHTML = data.map(chapter => ` -
-
- -
-

第${chapter.id}章 ${chapter.title}

- ${chapter.date} -
-

${chapter.subtitle}

-

${chapter.desc}

-
-
- `).join(''); -} - -function setupFilters() { - const filterTabs = document.querySelectorAll('.filter-tab'); - - filterTabs.forEach(tab => { - tab.addEventListener('click', () => { - filterTabs.forEach(t => t.classList.remove('active')); - tab.classList.add('active'); - - const filter = tab.dataset.filter; - filterChapters(filter); - }); - }); -} - -function filterChapters(filter) { - const items = document.querySelectorAll('.timeline-item'); - const data = window.chaptersData || chaptersData; - - items.forEach((item, index) => { - let show = true; - - if (filter === 'latest') { - show = index >= data.length - 5; - } else if (filter === 'unread') { - const chapterId = parseInt(item.dataset.chapter); - const readChapters = JSON.parse(localStorage.getItem('readChapters') || '[]'); - show = !readChapters.includes(chapterId); - } - - if (show) { - item.classList.remove('hidden'); - item.style.display = ''; - } else { - item.classList.add('hidden'); - item.style.display = 'none'; - } - }); -} - -function setupSearch() { - const searchInput = document.getElementById('searchInput'); - if (!searchInput) return; - - searchInput.addEventListener('input', (e) => { - const query = e.target.value.toLowerCase(); - const items = document.querySelectorAll('.timeline-item'); - - items.forEach(item => { - const title = item.querySelector('h3').textContent.toLowerCase(); - const desc = item.querySelector('.timeline-desc').textContent.toLowerCase(); - const match = title.includes(query) || desc.includes(query); - - if (match) { - item.classList.remove('hidden'); - item.style.display = ''; - } else { - item.classList.add('hidden'); - item.style.display = 'none'; - } - }); - }); -} - -function updateReadingProgress() { - const readChapters = JSON.parse(localStorage.getItem('readChapters') || '[]'); - const data = window.chaptersData || chaptersData; - const progress = Math.round((readChapters.length / data.length) * 100); - - const progressFill = document.getElementById('progressFill'); - const progressText = document.getElementById('progressText'); - - if (progressFill) progressFill.style.width = `${progress}%`; - if (progressText) progressText.textContent = `阅读进度 ${progress}%`; -} - -// ==================== 阅读器 ==================== -async function initReader() { - // 确保数据已加载 - if (!isDataLoaded) { - await loadChaptersData(); - } - - // 获取章节参数 - const urlParams = new URLSearchParams(window.location.search); - const chapterId = parseInt(urlParams.get('id')) || 1; - - // 加载章节内容 - await loadChapter(chapterId); - - // 初始化阅读器设置 - initReaderSettings(); - - // 初始化导航 - initReaderNav(chapterId); - - // 初始化侧边栏 - initSidebar(); - - // 记录阅读进度 - recordReadingProgress(chapterId); - - // 自动隐藏头部和底部 - initAutoHide(); -} - -async function loadChapter(chapterId) { - const chapter = chaptersData.find(c => c.id === chapterId); - if (!chapter) { - // 尝试从JSON文件直接加载 - try { - const chapterIdStr = chapterId.toString().padStart(2, '0'); - const response = await fetch(`data/chapter-${chapterIdStr}.json`); - if (response.ok) { - const data = await response.json(); - const normalizedData = normalizeChapterData(data, chapterId); - renderChapterContent(normalizedData); - return; - } - } catch (error) { - console.error('加载章节失败:', error); - } - return; - } - - renderChapterContent(chapter); -} - -function renderChapterContent(chapter) { - // 更新标题 - const chapterTitleEl = document.getElementById('chapterTitle'); - if (chapterTitleEl) { - chapterTitleEl.textContent = chapter.title; - } - document.title = `${chapter.title} - 阿拉德:剑之回响`; - - // 加载内容 - const contentEl = document.getElementById('chapterContent'); - if (contentEl) { - // 将内容中的换行转换为段落 - const paragraphs = chapter.content.split('\n\n').filter(p => p.trim()); - const contentHtml = paragraphs.map(p => { - // 处理分隔线 - if (p.trim() === '---') { - return '
'; - } - // 处理普通段落 - return `

${p.replace(/\n/g, '
')}

`; - }).join(''); - - contentEl.innerHTML = ` -
-

${chapter.title}

-

${chapter.subtitle}

-
-
- ${contentHtml} -
- - `; - } -} - -function initReaderNav(currentId) { - const prevBtn = document.getElementById('prevChapter'); - const nextBtn = document.getElementById('nextChapter'); - - const data = window.chaptersData || chaptersData; - - if (prevBtn) { - if (currentId > 1) { - prevBtn.disabled = false; - prevBtn.onclick = () => { - window.location.href = `reader.html?id=${currentId - 1}`; - }; - } else { - prevBtn.disabled = true; - } - } - - if (nextBtn) { - if (currentId < data.length) { - nextBtn.disabled = false; - nextBtn.onclick = () => { - window.location.href = `reader.html?id=${currentId + 1}`; - }; - } else { - nextBtn.disabled = true; - } - } -} - -function initSidebar() { - const openSidebar = document.getElementById('openSidebar'); - const sidebarClose = document.getElementById('sidebarClose'); - const readerSidebar = document.getElementById('readerSidebar'); - const overlay = document.getElementById('overlay'); - - // 生成侧边栏章节列表 - const sidebarChapters = document.getElementById('sidebarChapters'); - if (sidebarChapters) { - const data = window.chaptersData || chaptersData; - const currentId = getCurrentChapterId(); - - sidebarChapters.innerHTML = data.map(chapter => ` - - ${chapter.id} - ${chapter.title} - - `).join(''); - } - - if (openSidebar && readerSidebar && overlay) { - openSidebar.addEventListener('click', () => { - readerSidebar.classList.add('active'); - overlay.classList.add('active'); - }); - } - - if (sidebarClose && readerSidebar && overlay) { - sidebarClose.addEventListener('click', () => { - readerSidebar.classList.remove('active'); - overlay.classList.remove('active'); - }); - } - - if (overlay && readerSidebar) { - overlay.addEventListener('click', () => { - readerSidebar.classList.remove('active'); - overlay.classList.remove('active'); - }); - } -} - -function getCurrentChapterId() { - const urlParams = new URLSearchParams(window.location.search); - return parseInt(urlParams.get('id')) || 1; -} - -function recordReadingProgress(chapterId) { - let readChapters = JSON.parse(localStorage.getItem('readChapters') || '[]'); - if (!readChapters.includes(chapterId)) { - readChapters.push(chapterId); - localStorage.setItem('readChapters', JSON.stringify(readChapters)); - } - localStorage.setItem('lastReadChapter', chapterId); -} - -function initAutoHide() { - const header = document.getElementById('readerHeader'); - const footer = document.getElementById('readerFooter'); - let lastScrollY = window.scrollY; - let ticking = false; - - window.addEventListener('scroll', () => { - if (!ticking) { - window.requestAnimationFrame(() => { - const currentScrollY = window.scrollY; - - if (currentScrollY > lastScrollY && currentScrollY > 100) { - // 向下滚动,隐藏 - header?.classList.add('hidden'); - footer?.classList.add('hidden'); - } else { - // 向上滚动,显示 - header?.classList.remove('hidden'); - footer?.classList.remove('hidden'); - } - - lastScrollY = currentScrollY; - ticking = false; - }); - ticking = true; - } - }); -} - -// ==================== 工具函数 ==================== -function debounce(func, wait) { - let timeout; - return function executedFunction(...args) { - const later = () => { - clearTimeout(timeout); - func(...args); - }; - clearTimeout(timeout); - timeout = setTimeout(later, wait); - }; -} - -function throttle(func, limit) { - let inThrottle; - return function(...args) { - if (!inThrottle) { - func.apply(this, args); - inThrottle = true; - setTimeout(() => inThrottle = false, limit); - } - }; -} - -// ==================== 回到顶部按钮 ==================== -function initScrollTop() { - const scrollTopBtn = document.getElementById('scrollTop'); - if (!scrollTopBtn) return; - - // 点击回到顶部 - scrollTopBtn.addEventListener('click', () => { - window.scrollTo({ - top: 0, - behavior: 'smooth' - }); - }); - - // 滚动时显示/隐藏按钮 - const toggleVisibility = () => { - if (window.pageYOffset > 300) { - scrollTopBtn.style.opacity = '1'; - scrollTopBtn.style.visibility = 'visible'; - } else { - scrollTopBtn.style.opacity = '0'; - scrollTopBtn.style.visibility = 'hidden'; - } - }; - - // 初始状态隐藏 - scrollTopBtn.style.opacity = '0'; - scrollTopBtn.style.visibility = 'hidden'; - scrollTopBtn.style.transition = 'opacity 0.3s ease, visibility 0.3s ease'; - - window.addEventListener('scroll', throttle(toggleVisibility, 100)); -} - -// ==================== 独立章节页面初始化 ==================== -async function initChapterReader() { - // 确保数据已加载 - if (!isDataLoaded) { - await loadChaptersData(); - } - - const openSidebar = document.getElementById('openSidebar'); - const sidebarClose = document.getElementById('sidebarClose'); - const readerSidebar = document.getElementById('readerSidebar'); - const overlay = document.getElementById('overlay'); - const progressFill = document.getElementById('progressFill'); - - const data = window.chaptersData || chaptersData; - - // 动态计算进度条(基于总章节数) - if (progressFill) { - const totalChapters = data.length; - const currentChapterMatch = window.location.pathname.match(/chapter-(\d+)\.html/); - const currentChapter = currentChapterMatch ? parseInt(currentChapterMatch[1]) : 1; - const progress = Math.round((currentChapter / totalChapters) * 100); - progressFill.style.width = progress + '%'; - } - - // 生成侧边栏章节列表 - if (readerSidebar) { - const sidebarChapters = document.getElementById('sidebarChapters'); - if (sidebarChapters) { - const currentChapterMatch = window.location.pathname.match(/chapter-(\d+)\.html/); - const currentChapter = currentChapterMatch ? parseInt(currentChapterMatch[1]) : 1; - - sidebarChapters.innerHTML = data.map(chapter => ` - - ${chapter.id} - ${chapter.title} - - `).join(''); - } - } - - if (openSidebar && readerSidebar && overlay) { - openSidebar.addEventListener('click', () => { - readerSidebar.classList.add('active'); - overlay.classList.add('active'); - }); - } - - if (sidebarClose && readerSidebar && overlay) { - sidebarClose.addEventListener('click', () => { - readerSidebar.classList.remove('active'); - overlay.classList.remove('active'); - }); - } - - if (overlay && readerSidebar) { - overlay.addEventListener('click', () => { - readerSidebar.classList.remove('active'); - overlay.classList.remove('active'); - }); - } -} - -// ==================== 阅读器设置 ==================== -function initReaderSettings() { - const settingsBtn = document.getElementById('readerSettings'); - const settingsPanel = document.getElementById('settingsPanel'); - - if (!settingsBtn || !settingsPanel) return; - - // 切换设置面板显示 - settingsBtn.addEventListener('click', (e) => { - e.stopPropagation(); - settingsPanel.classList.toggle('active'); - }); - - // 点击外部关闭面板 - document.addEventListener('click', (e) => { - if (!settingsPanel.contains(e.target) && e.target !== settingsBtn) { - settingsPanel.classList.remove('active'); - } - }); - - // 初始化主题 - initThemeSettings(); - - // 初始化字体大小 - initFontSize(); - - // 初始化行间距 - initLineHeight(); - - // 初始化阅读宽度 - initReadWidth(); -} - -// 主题设置 -function initThemeSettings() { - const themeOptions = document.querySelectorAll('.theme-option'); - const savedTheme = localStorage.getItem('readerTheme') || 'dark'; - - // 应用保存的主题 - document.documentElement.setAttribute('data-theme', savedTheme); - - // 设置激活状态 - themeOptions.forEach(option => { - if (option.dataset.theme === savedTheme) { - option.classList.add('active'); - } - - option.addEventListener('click', () => { - const theme = option.dataset.theme; - document.documentElement.setAttribute('data-theme', theme); - localStorage.setItem('readerTheme', theme); - - themeOptions.forEach(o => o.classList.remove('active')); - option.classList.add('active'); - }); - }); -} - -// 字体大小设置 -function initFontSize() { - const decreaseBtn = document.getElementById('fontDecrease'); - const increaseBtn = document.getElementById('fontIncrease'); - const fontValue = document.getElementById('fontValue'); - const content = document.querySelector('.chapter-article') || document.getElementById('chapterContent'); - - if (!content) return; - - const sizes = ['14px', '16px', '18px', '20px', '22px', '24px']; - let currentSize = localStorage.getItem('readerFontSize') || '18px'; - - // 应用保存的字体大小 - content.style.fontSize = currentSize; - if (fontValue) fontValue.textContent = currentSize; - - decreaseBtn?.addEventListener('click', () => { - const index = sizes.indexOf(currentSize); - if (index > 0) { - currentSize = sizes[index - 1]; - content.style.fontSize = currentSize; - if (fontValue) fontValue.textContent = currentSize; - localStorage.setItem('readerFontSize', currentSize); - } - }); - - increaseBtn?.addEventListener('click', () => { - const index = sizes.indexOf(currentSize); - if (index < sizes.length - 1) { - currentSize = sizes[index + 1]; - content.style.fontSize = currentSize; - if (fontValue) fontValue.textContent = currentSize; - localStorage.setItem('readerFontSize', currentSize); - } - }); -} - -// 行间距设置 -function initLineHeight() { - const lineHeightBtns = document.querySelectorAll('.line-height-btn'); - const content = document.querySelector('.chapter-article') || document.getElementById('chapterContent'); - - if (!content) return; - - const savedLineHeight = localStorage.getItem('readerLineHeight') || '1.8'; - content.style.lineHeight = savedLineHeight; - - lineHeightBtns.forEach(btn => { - if (btn.dataset.value === savedLineHeight) { - btn.classList.add('active'); - } - - btn.addEventListener('click', () => { - const value = btn.dataset.value; - content.style.lineHeight = value; - localStorage.setItem('readerLineHeight', value); - - lineHeightBtns.forEach(b => b.classList.remove('active')); - btn.classList.add('active'); - }); - }); -} - -// 阅读宽度设置 -function initReadWidth() { - const widthBtns = document.querySelectorAll('.width-btn'); - const content = document.querySelector('.reader-content'); - - if (!content) return; - - const savedWidth = localStorage.getItem('readerWidth') || 'medium'; - applyWidth(content, savedWidth); - - widthBtns.forEach(btn => { - if (btn.dataset.width === savedWidth) { - btn.classList.add('active'); - } - - btn.addEventListener('click', () => { - const width = btn.dataset.width; - applyWidth(content, width); - localStorage.setItem('readerWidth', width); - - widthBtns.forEach(b => b.classList.remove('active')); - btn.classList.add('active'); - }); - }); -} - -function applyWidth(content, width) { - const widths = { - narrow: '680px', - medium: '800px', - wide: '100%' - }; - content.style.maxWidth = widths[width] || widths.medium; -} +// ==================== 章节数据管理 ==================== +// 自动从 data/chapter-*.json 文件加载章节数据 +let chaptersData = []; +let isDataLoaded = false; + +// 加载所有章节数据 +async function loadChaptersData() { + if (isDataLoaded) return chaptersData; + + const chapters = []; + let chapterNum = 1; + + // 循环加载章节,直到找不到文件 + while (true) { + try { + // 格式化章节号(带前导零) + const chapterId = chapterNum.toString().padStart(2, '0'); + const response = await fetch(`data/chapter-${chapterId}.json`, { + cache: 'no-store', + headers: { + 'Cache-Control': 'no-cache', + 'Pragma': 'no-cache' + } + }); + + if (!response.ok) { + // 尝试不带前导零的格式 + const response2 = await fetch(`data/chapter-${chapterNum}.json`, { + cache: 'no-store', + headers: { + 'Cache-Control': 'no-cache', + 'Pragma': 'no-cache' + } + }); + if (!response2.ok) break; + const data = await response2.json(); + chapters.push(normalizeChapterData(data, chapterNum)); + } else { + const data = await response.json(); + chapters.push(normalizeChapterData(data, chapterNum)); + } + + chapterNum++; + } catch (error) { + // 没有更多章节了 + break; + } + } + + chaptersData = chapters; + isDataLoaded = true; + + // 将数据挂载到 window 对象,供其他函数使用 + window.chaptersData = chaptersData; + + return chaptersData; +} + +// 标准化章节数据 +function normalizeChapterData(data, defaultId) { + // 从内容中提取描述(前100个字符) + const extractDesc = (content) => { + if (!content) return ''; + // 去除换行和多余空格,取前100字符 + const cleanContent = content.replace(/\n/g, ' ').replace(/\s+/g, ' ').trim(); + return cleanContent.substring(0, 100) + (cleanContent.length > 100 ? '...' : ''); + }; + + return { + id: data.id || defaultId, + title: data.title || `第${defaultId}章`, + subtitle: data.subtitle || '', + desc: data.desc || extractDesc(data.content), + content: data.content || '', + status: data.status || '已完结', + date: data.date || '2026-03-26' + }; +} + +// ==================== DOM加载完成后初始化 ==================== +document.addEventListener('DOMContentLoaded', async function() { + // 先加载章节数据 + await loadChaptersData(); + + initTheme(); + initNavigation(); + initParticles(); + + // 根据页面类型初始化不同功能 + const currentPage = window.location.pathname.split('/').pop() || 'index.html'; + + if (currentPage === 'index.html' || currentPage === '') { + renderLatestChapters(); + } else if (currentPage === 'chapters.html') { + renderChaptersList(); + setupFilters(); + setupSearch(); + updateReadingProgress(); + } else if (currentPage === 'reader.html') { + initReader(); + } else if (currentPage.startsWith('chapter-')) { + // 独立章节页面初始化 + initChapterReader(); + } + + // 初始化回到顶部按钮 + initScrollTop(); + + // 初始化阅读器设置 + initReaderSettings(); +}); + +// ==================== 主题切换 ==================== +function initTheme() { + const themeToggle = document.getElementById('themeToggle'); + if (!themeToggle) return; + + // 检查本地存储的主题 + const savedTheme = localStorage.getItem('theme') || 'dark'; + document.documentElement.setAttribute('data-theme', savedTheme); + updateThemeIcon(savedTheme); + + themeToggle.addEventListener('click', () => { + const currentTheme = document.documentElement.getAttribute('data-theme'); + const newTheme = currentTheme === 'dark' ? 'light' : 'dark'; + + document.documentElement.setAttribute('data-theme', newTheme); + localStorage.setItem('theme', newTheme); + updateThemeIcon(newTheme); + }); +} + +function updateThemeIcon(theme) { + const themeToggle = document.getElementById('themeToggle'); + if (!themeToggle) return; + + const icon = themeToggle.querySelector('.theme-icon'); + if (icon) { + icon.textContent = theme === 'dark' ? '🌙' : '☀️'; + } +} + +// ==================== 导航栏 ==================== +function initNavigation() { + const menuToggle = document.getElementById('menuToggle'); + const navLinks = document.querySelector('.nav-links'); + + if (menuToggle && navLinks) { + menuToggle.addEventListener('click', () => { + navLinks.classList.toggle('active'); + menuToggle.classList.toggle('active'); + }); + } + + // 导航栏滚动效果 + let lastScroll = 0; + const navbar = document.querySelector('.navbar'); + + if (navbar) { + window.addEventListener('scroll', () => { + const currentScroll = window.pageYOffset; + + if (currentScroll > 100) { + navbar.style.background = 'rgba(15, 15, 26, 0.95)'; + } else { + navbar.style.background = 'rgba(15, 15, 26, 0.8)'; + } + + lastScroll = currentScroll; + }); + } +} + +// ==================== 粒子效果 ==================== +function initParticles() { + const particlesContainer = document.getElementById('particles'); + if (!particlesContainer) return; + + // 创建粒子 + for (let i = 0; i < 30; i++) { + const particle = document.createElement('div'); + particle.className = 'particle'; + particle.style.cssText = ` + position: absolute; + width: ${Math.random() * 4 + 2}px; + height: ${Math.random() * 4 + 2}px; + background: rgba(99, 102, 241, ${Math.random() * 0.3 + 0.1}); + border-radius: 50%; + left: ${Math.random() * 100}%; + top: ${Math.random() * 100}%; + animation: particleFloat ${Math.random() * 10 + 10}s ease-in-out infinite; + animation-delay: ${Math.random() * 5}s; + `; + particlesContainer.appendChild(particle); + } +} + +// ==================== 首页最新章节 ==================== +function renderLatestChapters() { + const container = document.getElementById('latestChapters'); + if (!container) return; + + // 获取最新的6章 + const latestChapters = chaptersData.slice(-6).reverse(); + + container.innerHTML = latestChapters.map(chapter => ` + +
${chapter.id}
+
+

${chapter.title}

+

${chapter.desc}

+
+ ${chapter.date} + ${chapter.status} +
+
+
+ `).join(''); +} + +// ==================== 章节列表页 ==================== +function renderChaptersList() { + const container = document.getElementById('chaptersList'); + if (!container) return; + + // 使用加载的章节数据 + const data = window.chaptersData || chaptersData; + + container.innerHTML = data.map(chapter => ` +
+
+ +
+

第${chapter.id}章 ${chapter.title}

+ ${chapter.date} +
+

${chapter.subtitle}

+

${chapter.desc}

+
+
+ `).join(''); +} + +function setupFilters() { + const filterTabs = document.querySelectorAll('.filter-tab'); + + filterTabs.forEach(tab => { + tab.addEventListener('click', () => { + filterTabs.forEach(t => t.classList.remove('active')); + tab.classList.add('active'); + + const filter = tab.dataset.filter; + filterChapters(filter); + }); + }); +} + +function filterChapters(filter) { + const items = document.querySelectorAll('.timeline-item'); + const data = window.chaptersData || chaptersData; + + items.forEach((item, index) => { + let show = true; + + if (filter === 'latest') { + show = index >= data.length - 5; + } else if (filter === 'unread') { + const chapterId = parseInt(item.dataset.chapter); + const readChapters = JSON.parse(localStorage.getItem('readChapters') || '[]'); + show = !readChapters.includes(chapterId); + } + + if (show) { + item.classList.remove('hidden'); + item.style.display = ''; + } else { + item.classList.add('hidden'); + item.style.display = 'none'; + } + }); +} + +function setupSearch() { + const searchInput = document.getElementById('searchInput'); + if (!searchInput) return; + + searchInput.addEventListener('input', (e) => { + const query = e.target.value.toLowerCase(); + const items = document.querySelectorAll('.timeline-item'); + + items.forEach(item => { + const title = item.querySelector('h3').textContent.toLowerCase(); + const desc = item.querySelector('.timeline-desc').textContent.toLowerCase(); + const match = title.includes(query) || desc.includes(query); + + if (match) { + item.classList.remove('hidden'); + item.style.display = ''; + } else { + item.classList.add('hidden'); + item.style.display = 'none'; + } + }); + }); +} + +function updateReadingProgress() { + const readChapters = JSON.parse(localStorage.getItem('readChapters') || '[]'); + const data = window.chaptersData || chaptersData; + const progress = Math.round((readChapters.length / data.length) * 100); + + const progressFill = document.getElementById('progressFill'); + const progressText = document.getElementById('progressText'); + + if (progressFill) progressFill.style.width = `${progress}%`; + if (progressText) progressText.textContent = `阅读进度 ${progress}%`; +} + +// ==================== 阅读器 ==================== +async function initReader() { + // 确保数据已加载 + if (!isDataLoaded) { + await loadChaptersData(); + } + + // 获取章节参数 + const urlParams = new URLSearchParams(window.location.search); + const chapterId = parseInt(urlParams.get('id')) || 1; + + // 加载章节内容 + await loadChapter(chapterId); + + // 初始化阅读器设置 + initReaderSettings(); + + // 初始化导航 + initReaderNav(chapterId); + + // 初始化侧边栏 + initSidebar(); + + // 记录阅读进度 + recordReadingProgress(chapterId); + + // 自动隐藏头部和底部 + initAutoHide(); +} + +async function loadChapter(chapterId) { + const chapter = chaptersData.find(c => c.id === chapterId); + if (!chapter) { + // 尝试从JSON文件直接加载 + try { + const chapterIdStr = chapterId.toString().padStart(2, '0'); + const response = await fetch(`data/chapter-${chapterIdStr}.json`); + if (response.ok) { + const data = await response.json(); + const normalizedData = normalizeChapterData(data, chapterId); + renderChapterContent(normalizedData); + return; + } + } catch (error) { + console.error('加载章节失败:', error); + } + return; + } + + renderChapterContent(chapter); +} + +function renderChapterContent(chapter) { + // 更新标题 + const chapterTitleEl = document.getElementById('chapterTitle'); + if (chapterTitleEl) { + chapterTitleEl.textContent = chapter.title; + } + document.title = `${chapter.title} - 阿拉德:剑之回响`; + + // 加载内容 + const contentEl = document.getElementById('chapterContent'); + if (contentEl) { + // 将内容中的换行转换为段落 + const paragraphs = chapter.content.split('\n\n').filter(p => p.trim()); + const contentHtml = paragraphs.map(p => { + // 处理分隔线 + if (p.trim() === '---') { + return '
'; + } + // 处理普通段落 + return `

${p.replace(/\n/g, '
')}

`; + }).join(''); + + contentEl.innerHTML = ` +
+

${chapter.title}

+

${chapter.subtitle}

+
+
+ ${contentHtml} +
+ + `; + } +} + +function initReaderNav(currentId) { + const prevBtn = document.getElementById('prevChapter'); + const nextBtn = document.getElementById('nextChapter'); + + const data = window.chaptersData || chaptersData; + + if (prevBtn) { + if (currentId > 1) { + prevBtn.disabled = false; + prevBtn.onclick = () => { + window.location.href = `reader.html?id=${currentId - 1}`; + }; + } else { + prevBtn.disabled = true; + } + } + + if (nextBtn) { + if (currentId < data.length) { + nextBtn.disabled = false; + nextBtn.onclick = () => { + window.location.href = `reader.html?id=${currentId + 1}`; + }; + } else { + nextBtn.disabled = true; + } + } +} + +function initSidebar() { + const openSidebar = document.getElementById('openSidebar'); + const sidebarClose = document.getElementById('sidebarClose'); + const readerSidebar = document.getElementById('readerSidebar'); + const overlay = document.getElementById('overlay'); + + // 生成侧边栏章节列表 + const sidebarChapters = document.getElementById('sidebarChapters'); + if (sidebarChapters) { + const data = window.chaptersData || chaptersData; + const currentId = getCurrentChapterId(); + + sidebarChapters.innerHTML = data.map(chapter => ` + + ${chapter.id} + ${chapter.title} + + `).join(''); + } + + if (openSidebar && readerSidebar && overlay) { + openSidebar.addEventListener('click', () => { + readerSidebar.classList.add('active'); + overlay.classList.add('active'); + }); + } + + if (sidebarClose && readerSidebar && overlay) { + sidebarClose.addEventListener('click', () => { + readerSidebar.classList.remove('active'); + overlay.classList.remove('active'); + }); + } + + if (overlay && readerSidebar) { + overlay.addEventListener('click', () => { + readerSidebar.classList.remove('active'); + overlay.classList.remove('active'); + }); + } +} + +function getCurrentChapterId() { + const urlParams = new URLSearchParams(window.location.search); + return parseInt(urlParams.get('id')) || 1; +} + +function recordReadingProgress(chapterId) { + let readChapters = JSON.parse(localStorage.getItem('readChapters') || '[]'); + if (!readChapters.includes(chapterId)) { + readChapters.push(chapterId); + localStorage.setItem('readChapters', JSON.stringify(readChapters)); + } + localStorage.setItem('lastReadChapter', chapterId); +} + +function initAutoHide() { + const header = document.getElementById('readerHeader'); + const footer = document.getElementById('readerFooter'); + let lastScrollY = window.scrollY; + let ticking = false; + + window.addEventListener('scroll', () => { + if (!ticking) { + window.requestAnimationFrame(() => { + const currentScrollY = window.scrollY; + + if (currentScrollY > lastScrollY && currentScrollY > 100) { + // 向下滚动,隐藏 + header?.classList.add('hidden'); + footer?.classList.add('hidden'); + } else { + // 向上滚动,显示 + header?.classList.remove('hidden'); + footer?.classList.remove('hidden'); + } + + lastScrollY = currentScrollY; + ticking = false; + }); + ticking = true; + } + }); +} + +// ==================== 工具函数 ==================== +function debounce(func, wait) { + let timeout; + return function executedFunction(...args) { + const later = () => { + clearTimeout(timeout); + func(...args); + }; + clearTimeout(timeout); + timeout = setTimeout(later, wait); + }; +} + +function throttle(func, limit) { + let inThrottle; + return function(...args) { + if (!inThrottle) { + func.apply(this, args); + inThrottle = true; + setTimeout(() => inThrottle = false, limit); + } + }; +} + +// ==================== 回到顶部按钮 ==================== +function initScrollTop() { + const scrollTopBtn = document.getElementById('scrollTop'); + if (!scrollTopBtn) return; + + // 点击回到顶部 + scrollTopBtn.addEventListener('click', () => { + window.scrollTo({ + top: 0, + behavior: 'smooth' + }); + }); + + // 滚动时显示/隐藏按钮 + const toggleVisibility = () => { + if (window.pageYOffset > 300) { + scrollTopBtn.style.opacity = '1'; + scrollTopBtn.style.visibility = 'visible'; + } else { + scrollTopBtn.style.opacity = '0'; + scrollTopBtn.style.visibility = 'hidden'; + } + }; + + // 初始状态隐藏 + scrollTopBtn.style.opacity = '0'; + scrollTopBtn.style.visibility = 'hidden'; + scrollTopBtn.style.transition = 'opacity 0.3s ease, visibility 0.3s ease'; + + window.addEventListener('scroll', throttle(toggleVisibility, 100)); +} + +// ==================== 独立章节页面初始化 ==================== +async function initChapterReader() { + // 确保数据已加载 + if (!isDataLoaded) { + await loadChaptersData(); + } + + const openSidebar = document.getElementById('openSidebar'); + const sidebarClose = document.getElementById('sidebarClose'); + const readerSidebar = document.getElementById('readerSidebar'); + const overlay = document.getElementById('overlay'); + const progressFill = document.getElementById('progressFill'); + + const data = window.chaptersData || chaptersData; + + // 动态计算进度条(基于总章节数) + if (progressFill) { + const totalChapters = data.length; + const currentChapterMatch = window.location.pathname.match(/chapter-(\d+)\.html/); + const currentChapter = currentChapterMatch ? parseInt(currentChapterMatch[1]) : 1; + const progress = Math.round((currentChapter / totalChapters) * 100); + progressFill.style.width = progress + '%'; + } + + // 生成侧边栏章节列表 + if (readerSidebar) { + const sidebarChapters = document.getElementById('sidebarChapters'); + if (sidebarChapters) { + const currentChapterMatch = window.location.pathname.match(/chapter-(\d+)\.html/); + const currentChapter = currentChapterMatch ? parseInt(currentChapterMatch[1]) : 1; + + sidebarChapters.innerHTML = data.map(chapter => ` + + ${chapter.id} + ${chapter.title} + + `).join(''); + } + } + + if (openSidebar && readerSidebar && overlay) { + openSidebar.addEventListener('click', () => { + readerSidebar.classList.add('active'); + overlay.classList.add('active'); + }); + } + + if (sidebarClose && readerSidebar && overlay) { + sidebarClose.addEventListener('click', () => { + readerSidebar.classList.remove('active'); + overlay.classList.remove('active'); + }); + } + + if (overlay && readerSidebar) { + overlay.addEventListener('click', () => { + readerSidebar.classList.remove('active'); + overlay.classList.remove('active'); + }); + } +} + +// ==================== 阅读器设置 ==================== +function initReaderSettings() { + const settingsBtn = document.getElementById('readerSettings'); + const settingsPanel = document.getElementById('settingsPanel'); + + if (!settingsBtn || !settingsPanel) return; + + // 切换设置面板显示 + settingsBtn.addEventListener('click', (e) => { + e.stopPropagation(); + settingsPanel.classList.toggle('active'); + }); + + // 点击外部关闭面板 + document.addEventListener('click', (e) => { + if (!settingsPanel.contains(e.target) && e.target !== settingsBtn) { + settingsPanel.classList.remove('active'); + } + }); + + // 初始化主题 + initThemeSettings(); + + // 初始化字体大小 + initFontSize(); + + // 初始化行间距 + initLineHeight(); + + // 初始化阅读宽度 + initReadWidth(); +} + +// 主题设置 +function initThemeSettings() { + const themeOptions = document.querySelectorAll('.theme-option'); + const savedTheme = localStorage.getItem('readerTheme') || 'dark'; + + // 应用保存的主题 + document.documentElement.setAttribute('data-theme', savedTheme); + + // 设置激活状态 + themeOptions.forEach(option => { + if (option.dataset.theme === savedTheme) { + option.classList.add('active'); + } + + option.addEventListener('click', () => { + const theme = option.dataset.theme; + document.documentElement.setAttribute('data-theme', theme); + localStorage.setItem('readerTheme', theme); + + themeOptions.forEach(o => o.classList.remove('active')); + option.classList.add('active'); + }); + }); +} + +// 字体大小设置 +function initFontSize() { + const decreaseBtn = document.getElementById('fontDecrease'); + const increaseBtn = document.getElementById('fontIncrease'); + const fontValue = document.getElementById('fontValue'); + const content = document.querySelector('.chapter-article') || document.getElementById('chapterContent'); + + if (!content) return; + + const sizes = ['14px', '16px', '18px', '20px', '22px', '24px']; + let currentSize = localStorage.getItem('readerFontSize') || '18px'; + + // 应用保存的字体大小 + content.style.fontSize = currentSize; + if (fontValue) fontValue.textContent = currentSize; + + decreaseBtn?.addEventListener('click', () => { + const index = sizes.indexOf(currentSize); + if (index > 0) { + currentSize = sizes[index - 1]; + content.style.fontSize = currentSize; + if (fontValue) fontValue.textContent = currentSize; + localStorage.setItem('readerFontSize', currentSize); + } + }); + + increaseBtn?.addEventListener('click', () => { + const index = sizes.indexOf(currentSize); + if (index < sizes.length - 1) { + currentSize = sizes[index + 1]; + content.style.fontSize = currentSize; + if (fontValue) fontValue.textContent = currentSize; + localStorage.setItem('readerFontSize', currentSize); + } + }); +} + +// 行间距设置 +function initLineHeight() { + const lineHeightBtns = document.querySelectorAll('.line-height-btn'); + const content = document.querySelector('.chapter-article') || document.getElementById('chapterContent'); + + if (!content) return; + + const savedLineHeight = localStorage.getItem('readerLineHeight') || '1.8'; + content.style.lineHeight = savedLineHeight; + + lineHeightBtns.forEach(btn => { + if (btn.dataset.value === savedLineHeight) { + btn.classList.add('active'); + } + + btn.addEventListener('click', () => { + const value = btn.dataset.value; + content.style.lineHeight = value; + localStorage.setItem('readerLineHeight', value); + + lineHeightBtns.forEach(b => b.classList.remove('active')); + btn.classList.add('active'); + }); + }); +} + +// 阅读宽度设置 +function initReadWidth() { + const widthBtns = document.querySelectorAll('.width-btn'); + const content = document.querySelector('.reader-content'); + + if (!content) return; + + const savedWidth = localStorage.getItem('readerWidth') || 'medium'; + applyWidth(content, savedWidth); + + widthBtns.forEach(btn => { + if (btn.dataset.width === savedWidth) { + btn.classList.add('active'); + } + + btn.addEventListener('click', () => { + const width = btn.dataset.width; + applyWidth(content, width); + localStorage.setItem('readerWidth', width); + + widthBtns.forEach(b => b.classList.remove('active')); + btn.classList.add('active'); + }); + }); +} + +function applyWidth(content, width) { + const widths = { + narrow: '680px', + medium: '800px', + wide: '100%' + }; + content.style.maxWidth = widths[width] || widths.medium; +} diff --git a/alacarte-novel-website/template.html b/alacarte-novel-website/template.html index b8f9e1d..110d344 100644 --- a/alacarte-novel-website/template.html +++ b/alacarte-novel-website/template.html @@ -1,448 +1,451 @@ - - - - - - {{CHAPTER_TITLE}} - 阿拉德:剑之回响 - - - - - - - - - -
-
-
{{CHAPTER_NUMBER}}
-

{{CHAPTER_TITLE}}

-
- -
-{{CHAPTER_CONTENT}} -
-
- - - - - -
- - -
- - - - - - + + + + + + + + + {{CHAPTER_TITLE}} - 阿拉德:剑之回响 + + + + + + + + + +
+
+
{{CHAPTER_NUMBER}}
+

{{CHAPTER_TITLE}}

+
+ +
+{{CHAPTER_CONTENT}} +
+
+ + + + + +
+ + +
+ + + + + + \ No newline at end of file