feat 新增網路版介紹電子書

This commit is contained in:
2026-05-14 16:09:17 +08:00
parent 538547b490
commit 0986073b85
27 changed files with 986 additions and 428 deletions
Binary file not shown.

After

Width:  |  Height:  |  Size: 795 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 482 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 721 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 591 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 631 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 808 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 816 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 852 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 849 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 833 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 803 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 750 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 743 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 887 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 830 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 293 KiB

+39 -31
View File
@@ -3,30 +3,26 @@
const hubPanels = Array.from(document.querySelectorAll("[data-totoga-panel]"));
function setHubPanel(name) {
if (!hubButtons.length || !hubPanels.length) return;
hubButtons.forEach((btn) => btn.classList.toggle("active", btn.dataset.totogaHub === name));
hubPanels.forEach((panel) => {
panel.hidden = panel.dataset.totogaPanel !== name;
});
}
hubButtons.forEach((btn) => {
btn.addEventListener("click", () => setHubPanel(btn.dataset.totogaHub));
});
const reader = document.getElementById("totoga2-reader");
if (!reader) return;
const chapters = Array.from(reader.querySelectorAll(".chronicle-chapter"));
const chapters = reader ? Array.from(reader.querySelectorAll(".chronicle-chapter")) : [];
const modeButtons = Array.from(document.querySelectorAll("[data-totoga-reader-mode]"));
const pager = document.getElementById("totoga2-pager");
const prevBtn = document.getElementById("totoga2-prev");
const nextBtn = document.getElementById("totoga2-next");
const indicator = document.getElementById("totoga2-chapter-indicator");
if (!pager || !prevBtn || !nextBtn || !indicator) return;
const hasPager = Boolean(pager && prevBtn && nextBtn && indicator);
let currentIndex = 0;
function updatePagedView() {
if (!hasPager) return;
chapters.forEach((chapter, index) => {
chapter.style.display = index === currentIndex ? "" : "none";
chapter.classList.toggle("active", index === currentIndex);
@@ -37,13 +33,14 @@
}
function setReaderMode(mode) {
if (!reader) return;
reader.dataset.mode = mode;
modeButtons.forEach((btn) => btn.classList.toggle("active", btn.dataset.totogaReaderMode === mode));
if (mode === "paged") {
if (mode === "paged" && hasPager) {
pager.hidden = false;
updatePagedView();
} else {
pager.hidden = true;
if (pager) pager.hidden = true;
chapters.forEach((chapter) => {
chapter.style.display = "";
chapter.classList.remove("active");
@@ -55,37 +52,48 @@
button.addEventListener("click", () => setReaderMode(button.dataset.totogaReaderMode));
});
prevBtn.addEventListener("click", () => {
if (currentIndex > 0) {
currentIndex -= 1;
updatePagedView();
}
});
if (hasPager) {
prevBtn.addEventListener("click", () => {
if (currentIndex > 0) {
currentIndex -= 1;
updatePagedView();
}
});
nextBtn.addEventListener("click", () => {
if (currentIndex < chapters.length - 1) {
currentIndex += 1;
updatePagedView();
}
});
nextBtn.addEventListener("click", () => {
if (currentIndex < chapters.length - 1) {
currentIndex += 1;
updatePagedView();
}
});
}
const initialHub =
hubButtons.find((b) => b.classList.contains("active"))?.dataset.totogaHub ||
hubButtons[0]?.dataset.totogaHub ||
"video";
setHubPanel(initialHub);
setReaderMode("scroll");
if (hubButtons.length > 0) {
const initialHub =
hubButtons.find((b) => b.classList.contains("active"))?.dataset.totogaHub ||
hubButtons[0]?.dataset.totogaHub ||
"video";
setHubPanel(initialHub);
} else {
hubPanels.forEach((panel) => {
panel.hidden = false;
});
}
if (reader) {
setReaderMode("scroll");
}
function applyLocationHashNavigation() {
const hash = (location.hash || "").slice(1);
if (hash === "ebook") {
if (hash === "ebook" && hubButtons.length > 0) {
setHubPanel("ebook");
return;
}
if (hash && document.getElementById(hash)) {
setHubPanel("reader");
if (hubButtons.length > 0) setHubPanel("reader");
setReaderMode("scroll");
pager.hidden = true;
if (pager) pager.hidden = true;
requestAnimationFrame(() => {
document.getElementById(hash)?.scrollIntoView({ behavior: "smooth", block: "start" });
});