Skip to content

Commit b95cbdd

Browse files
committed
feat: code by Trae
1 parent 95f0f0c commit b95cbdd

2 files changed

Lines changed: 126 additions & 80 deletions

File tree

epub_browser/assets/chapter.css

Lines changed: 33 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -878,6 +878,7 @@ body {
878878
.pagination-mode .content-container {
879879
flex: 1;
880880
margin-bottom: 0;
881+
overflow: hidden;
881882
}
882883

883884
.pagination-mode .navigation {
@@ -889,13 +890,16 @@ body {
889890
}
890891

891892
.pagination-mode #eb-content {
892-
display: flex;
893-
flex-direction: column;
894893
height: 100%;
895-
position: relative;
896894
padding: 40px;
897895
margin: 0;
898896
width: 100%;
897+
column-width: 100%;
898+
column-height: 100%;
899+
column-fill: auto;
900+
column-gap: 0;
901+
overflow: hidden;
902+
position: relative;
899903
}
900904

901905
/* 隐藏滚动条 */
@@ -910,27 +914,37 @@ body {
910914
background: var(--bg-color);
911915
}
912916

913-
.pagination-page {
917+
/* CSS Column 分页样式 */
918+
.pagination-mode #eb-content {
914919
height: 100%;
915-
width: 100%;
916-
overflow-y: auto;
917-
box-sizing: border-box;
918-
position: absolute;
919-
top: 0;
920-
left: 0;
921-
opacity: 0;
922-
transform: translateX(100%);
923-
transition: opacity 0.3s ease, transform 0.4s ease;
920+
column-count: 1;
921+
column-fill: auto;
922+
column-gap: 0;
923+
overflow: hidden;
924924
}
925925

926-
.pagination-page.active {
927-
opacity: 1;
928-
transform: translateX(0);
929-
position: relative;
926+
/* 确保内容块不会被分割到不同页面 */
927+
.pagination-mode #eb-content > * {
928+
break-inside: avoid;
929+
page-break-inside: avoid;
930+
-webkit-column-break-inside: avoid;
930931
}
931932

932-
.pagination-page.prev {
933-
transform: translateX(-100%);
933+
/* 调整图片在分页模式下的显示 */
934+
.pagination-mode #eb-content img {
935+
max-width: 100%;
936+
height: auto;
937+
break-inside: avoid;
938+
page-break-inside: avoid;
939+
-webkit-column-break-inside: avoid;
940+
}
941+
942+
/* 调整表格在分页模式下的显示 */
943+
.pagination-mode #eb-content table {
944+
break-inside: avoid;
945+
page-break-inside: avoid;
946+
-webkit-column-break-inside: avoid;
947+
width: 100%;
934948
}
935949

936950
.kindle-mode .header, .kindle-mode .toc-container,

epub_browser/assets/chapter.js

Lines changed: 93 additions & 61 deletions
Original file line numberDiff line numberDiff line change
@@ -345,7 +345,8 @@ function initScript() {
345345
let isPaginationMode = false;
346346
let currentPage = 0;
347347
let totalPages = 0;
348-
let pages = [];
348+
let contentWidth = 0;
349+
let pageWidth = 0;
349350

350351
let fontSize = "small";
351352
let fontFamily = "system-ui, -apple-system, sans-serif";
@@ -434,7 +435,11 @@ function initScript() {
434435
enablePaginationMode();
435436
// 禁止翻页模式 点击页面链接
436437
document.querySelectorAll('.eb-content a').forEach(item => {
437-
item.removeAttribute('href');
438+
const originalHref = item.getAttribute('href');
439+
if (originalHref) {
440+
item.setAttribute('data-original-href', originalHref);
441+
item.removeAttribute('href');
442+
}
438443
});
439444
togglePaginationBtn.innerHTML = '<i class="fas fa-scroll"></i><span class="control-name">Scrolling</span>';
440445
mobileTogglePaginationBtn.innerHTML = '<i class="fas fa-scroll"></i><span class="control-name">Scrolling</span>';
@@ -448,6 +453,12 @@ function initScript() {
448453
if (mobileTocBtn) {
449454
mobileTocBtn.style.display = 'none';
450455
}
456+
457+
// 添加窗口大小改变事件监听
458+
window.addEventListener('resize', function() {
459+
calculateTotalPages();
460+
showPage(currentPage);
461+
});
451462
} else {
452463
loadReadingProgress(); // 刚进去是 scroll,也需要恢复下进度
453464
}
@@ -499,6 +510,15 @@ function initScript() {
499510
paginationInfo.style.display = 'flex';
500511
navigationHomeBtn.style.display = 'none';
501512

513+
// 保存链接的原始 href 属性,然后移除 href
514+
document.querySelectorAll('.eb-content a').forEach(item => {
515+
const originalHref = item.getAttribute('href');
516+
if (originalHref) {
517+
item.setAttribute('data-original-href', originalHref);
518+
item.removeAttribute('href');
519+
}
520+
});
521+
502522
// 分割内容为页面
503523
createPages();
504524

@@ -550,13 +570,10 @@ function initScript() {
550570
return content.innerHTML;
551571
}
552572

553-
// 创建页面
573+
// 创建页面 - 使用 CSS Column 实现
554574
function createPages() {
555575
// 保存原始内容
556-
// 预处理
557576
const originalContent = preprocessContent(content);
558-
let newContent = document.createElement("article");
559-
newContent.innerHTML = originalContent;
560577

561578
// 获取容器高度
562579
const bottomNav = document.querySelector('.navigation');
@@ -585,64 +602,45 @@ function initScript() {
585602

586603
pageHeightInput.value = contentHeight
587604

588-
// 分割内容为页面
589-
let currentPageContent = '';
590-
let currentHeight = 0;
591-
const elements = Array.from(newContent.children || []);
605+
// 应用 CSS Column 样式
606+
content.style.height = `${contentHeight}px`;
607+
content.style.columnCount = '1';
608+
content.style.columnFill = 'auto';
609+
content.style.columnGap = '0';
610+
611+
// 恢复原始内容
612+
content.innerHTML = originalContent;
613+
614+
// 计算总页数
615+
calculateTotalPages();
592616

593-
// 如果没有子元素,直接使用文本内容
594-
if (elements.length === 0) {
595-
pages = [originalContent];
596-
totalPages = 1;
597-
} else {
598-
// 遍历所有子元素
599-
elements.forEach(element => {
600-
let elementHeight = getElementHeight(element);
601-
// 如果当前页面高度加上新元素高度超过容器高度,创建新页面
602-
if (currentHeight + elementHeight > contentHeight && currentHeight > 0) {
603-
pages.push(currentPageContent);
604-
currentPageContent = '';
605-
currentHeight = 0;
606-
}
607-
// 添加元素到当前页面
608-
currentPageContent += element.outerHTML;
609-
currentHeight += elementHeight;
610-
});
611-
612-
// 添加最后一页
613-
if (currentPageContent) {
614-
pages.push(currentPageContent);
615-
}
616-
617-
totalPages = pages.length;
618-
}
619-
620617
pageJumpInput.setAttribute('max', totalPages);
621-
622-
// 清空内容容器
623-
content.innerHTML = '';
618+
}
619+
620+
// 计算总页数
621+
function calculateTotalPages() {
622+
// 获取内容和容器宽度
623+
pageWidth = content.clientWidth;
624+
contentWidth = content.scrollWidth;
624625

625-
// 创建页面元素
626-
pages.forEach((pageContent, index) => {
627-
const pageElement = document.createElement('div');
628-
pageElement.className = 'pagination-page';
629-
pageElement.innerHTML = pageContent;
630-
content.appendChild(pageElement);
631-
});
626+
// 计算总页数
627+
totalPages = Math.ceil(contentWidth / pageWidth);
628+
629+
// 更新总页数显示
630+
totalPagesEl.textContent = totalPages;
632631
}
633632

634-
// 显示指定页面
633+
// 显示指定页面 - 使用 CSS Column 实现
635634
function showPage(pageIndex) {
636-
// 隐藏所有页面
637-
document.querySelectorAll('.pagination-page').forEach(page => {
638-
page.classList.remove('active', 'prev');
639-
});
635+
// 确保页面索引在有效范围内
636+
if (pageIndex < 0) pageIndex = 0;
637+
if (pageIndex >= totalPages) pageIndex = totalPages - 1;
640638

641-
// 显示当前页面
642-
const currentPageElement = document.querySelectorAll('.pagination-page')[pageIndex];
643-
if (currentPageElement) {
644-
currentPageElement.classList.add('active');
645-
}
639+
// 计算滚动位置
640+
const scrollPosition = pageIndex * pageWidth;
641+
642+
// 滚动到指定位置
643+
content.scrollLeft = scrollPosition;
646644

647645
// 更新当前页面索引
648646
currentPage = pageIndex;
@@ -679,14 +677,48 @@ function initScript() {
679677

680678
// 恢复原始内容
681679
function restoreOriginalContent() {
682-
// 这里需要重新加载原始内容
683-
// 在实际应用中,您可能需要保存原始内容或重新获取
684-
// 这里我们简单重新加载页面
680+
// 移除分页模式类
681+
document.body.classList.remove('pagination-mode');
682+
contentContainer.classList.remove('pagination-mode');
683+
684+
// 恢复内容样式
685+
content.style.height = '';
686+
content.style.columnCount = '';
687+
content.style.columnFill = '';
688+
content.style.columnGap = '';
689+
690+
// 显示页面的必要元素
691+
toggleHideUnnecessary(false);
692+
693+
// 隐藏翻页信息
694+
paginationInfo.style.display = 'none';
695+
navigationHomeBtn.style.display = 'flex';
696+
697+
// 重新启用链接
698+
document.querySelectorAll('.eb-content a').forEach(item => {
699+
const originalHref = item.getAttribute('data-original-href');
700+
if (originalHref) {
701+
item.setAttribute('href', originalHref);
702+
item.removeAttribute('data-original-href');
703+
}
704+
});
705+
706+
// 显示目录按钮
707+
let tocToggleBtn = document.getElementById('tocToggle');
708+
if (tocToggleBtn) {
709+
tocToggleBtn.style.display = 'flex';
710+
}
711+
let mobileTocBtn = document.getElementById('mobileTocBtn');
712+
if (mobileTocBtn) {
713+
mobileTocBtn.style.display = 'flex';
714+
}
715+
716+
// 重新加载页面以确保所有样式和功能恢复正常
685717
if (isKindleMode() || confirm('Are you sure you want to exit the page-turning mode?')) {
686718
location.reload();
687719
} else {
688720
// 如果用户取消,重新启用翻页模式
689-
// 什么也不干
721+
enablePaginationMode();
690722
}
691723
}
692724

0 commit comments

Comments
 (0)