feat(前端界面): 统一侧栏上下留白,优化页面、目录和搜索的滚动体验
build.yaml / build (push) Successful in 38s

This commit is contained in:
xiaoqidun committed 2026-09-17 02:12:52 +08:00
1 parent 35f0722d36
commit 5e86e903e4
3 files changed
+45 -50

No files matched your search

+15 -13
View File
@@ -332,20 +332,22 @@
<button id="outlinesTab" type="button" role="tab" aria-selected="false" aria-controls="outlineList" tabindex="-1">目录</button>
<button id="searchTab" type="button" role="tab" aria-keyshortcuts="Control+F Meta+F" aria-selected="false" aria-controls="searchPanel" tabindex="-1">搜索</button>
</div>
<div id="pageList" class="page-list" role="tabpanel" aria-label="页面"></div>
<div id="outlineList" role="tabpanel" aria-label="目录" hidden></div>
<div id="searchPanel" role="tabpanel" aria-label="搜索" hidden>
<form id="searchForm" class="search-form" role="search">
<input id="searchInput" type="search" aria-label="搜索文字" placeholder="搜索文字" autocomplete="off">
<button type="submit" class="button">搜索</button>
</form>
<div class="search-tools">
<span id="searchStatus" role="status" aria-live="polite"></span>
<span id="searchCount">0 / 0</span>
<button id="searchPrev" type="button" class="icon-button arrow-prev" title="上一处" aria-label="上一处" aria-keyshortcuts="Shift+F3" disabled></button>
<button id="searchNext" type="button" class="icon-button arrow-next" title="下一处" aria-label="下一处" aria-keyshortcuts="F3" disabled></button>
<div id="navigationContent" class="navigation-content">
<div id="pageList" class="page-list" role="tabpanel" aria-label="页面"></div>
<div id="outlineList" role="tabpanel" aria-label="目录" hidden></div>
<div id="searchPanel" role="tabpanel" aria-label="搜索" hidden>
<form id="searchForm" class="search-form" role="search">
<input id="searchInput" type="search" aria-label="搜索文字" placeholder="搜索文字" autocomplete="off">
<button type="submit" class="button">搜索</button>
</form>
<div class="search-tools">
<span id="searchStatus" role="status" aria-live="polite"></span>
<span id="searchCount">0 / 0</span>
<button id="searchPrev" type="button" class="icon-button arrow-prev" title="上一处" aria-label="上一处" aria-keyshortcuts="Shift+F3" disabled></button>
<button id="searchNext" type="button" class="icon-button arrow-next" title="下一处" aria-label="下一处" aria-keyshortcuts="F3" disabled></button>
</div>
<div id="searchResults" class="search-results"></div>
</div>
<div id="searchResults" class="search-results"></div>
</div>
</aside>
+15 -19
View File
@@ -848,7 +848,7 @@ body[data-hide-meta] .meta-panel {
display: none;
}
.page-list-panel,
.navigation-content,
.viewer-panel,
.search-results,
.editor-toolbar,
@@ -866,11 +866,16 @@ body[data-hide-meta] .meta-panel {
overflow: auto;
}
.page-list-item,
.outline-list summary,
.outline-link {
scroll-margin-top: 51px;
scroll-margin-bottom: 12px;
.page-list-panel {
display: flex;
flex-direction: column;
overflow: hidden;
}
.navigation-content {
flex: 1;
min-height: 0;
overflow: auto;
}
.meta-panel {
@@ -944,17 +949,11 @@ body[data-hide-meta] .meta-panel {
}
.navigation-tabs {
position: sticky;
top: -12px;
z-index: 1;
display: flex;
flex-shrink: 0;
gap: 16px;
margin-top: -12px;
margin-bottom: 10px;
padding-top: 12px;
margin-bottom: 12px;
border-bottom: 1px solid var(--line);
background: var(--panel);
box-shadow: 0 10px var(--panel);
}
.navigation-tabs button {
@@ -979,7 +978,7 @@ body[data-hide-meta] .meta-panel {
list-style: none;
}
body:not([data-hide-pages]) .page-list-panel:has(#searchPanel:not([hidden])),
.navigation-content:has(#searchPanel:not([hidden])),
#searchPanel:not([hidden]) {
display: flex;
flex-direction: column;
@@ -2262,15 +2261,12 @@ button.outline-link:hover {
transition: transform 0.18s ease;
}
body[data-hide-pages] .page-list-panel,
body[data-hide-meta] .meta-panel {
display: block;
}
body[data-hide-pages] .page-list-panel:has(#searchPanel:not([hidden])) {
body[data-hide-pages] .page-list-panel {
display: flex;
flex-direction: column;
overflow: hidden;
}
.page-list-panel {
+15 -18
View File
@@ -280,6 +280,7 @@ const el = {
pageListPanel: document.querySelector(".page-list-panel"),
pageListTitle: document.querySelector("#pageListTitle"),
navigationTabs: document.querySelector("#navigationTabs"),
navigationContent: document.querySelector("#navigationContent"),
pagesTab: document.querySelector("#pagesTab"),
outlinesTab: document.querySelector("#outlinesTab"),
pageList: document.querySelector("#pageList"),
@@ -2747,8 +2748,8 @@ async function openDocument(options = {}) {
if (options.resetScroll) {
el.viewerPanel.scrollLeft = 0;
el.viewerPanel.scrollTop = 0;
el.pageListPanel.scrollLeft = 0;
el.pageListPanel.scrollTop = 0;
el.navigationContent.scrollLeft = 0;
el.navigationContent.scrollTop = 0;
el.metaPanel.scrollLeft = 0;
el.metaPanel.scrollTop = 0;
}
@@ -3679,16 +3680,12 @@ function updatePageListCurrent(force = false) {
if (next) {
setPageItemCurrent(next, true);
if (state.showPages && !el.pageList.hidden) {
const panel = el.pageListPanel.getBoundingClientRect();
const panel = el.navigationContent.getBoundingClientRect();
const item = next.getBoundingClientRect();
const style = getComputedStyle(el.pageListPanel);
const top = Math.max(panel.top + Number.parseFloat(style.paddingTop),
el.navigationTabs.getBoundingClientRect().bottom + Number.parseFloat(getComputedStyle(el.navigationTabs).marginBottom));
const bottom = panel.bottom - Number.parseFloat(style.paddingBottom);
if (item.top < top) {
el.pageListPanel.scrollTop += item.top - top;
} else if (item.bottom > bottom) {
el.pageListPanel.scrollTop += Math.min(item.top - top, item.bottom - bottom);
if (item.top < panel.top) {
el.navigationContent.scrollTop += item.top - panel.top;
} else if (item.bottom > panel.bottom) {
el.navigationContent.scrollTop += Math.min(item.top - panel.top, item.bottom - panel.bottom);
}
}
}
@@ -3799,7 +3796,7 @@ function focusSearch() {
}
function showNavigation(selected) {
const scrollTop = el.pageListPanel.scrollTop;
const scrollTop = el.navigationContent.scrollTop;
for (const [tab, panel] of [[el.pagesTab, el.pageList], [el.outlinesTab, el.outlineList], [el.searchTab, el.searchPanel]]) {
if (tab.getAttribute("aria-selected") === "true") {
state.navigationScroll.set(tab, scrollTop);
@@ -3809,12 +3806,12 @@ function showNavigation(selected) {
tab.setAttribute("aria-selected", String(active));
tab.tabIndex = active ? 0 : -1;
}
el.pageListPanel.scrollTop = state.navigationScroll.get(selected) || 0;
el.navigationContent.scrollTop = state.navigationScroll.get(selected) || 0;
}
function renderOutlines(reset = true) {
const selected = !reset && [el.pagesTab, el.outlinesTab, el.searchTab].find(tab => tab.getAttribute("aria-selected") === "true");
const scrollTop = reset ? 0 : el.pageListPanel.scrollTop;
const scrollTop = reset ? 0 : el.navigationContent.scrollTop;
if (reset) {
state.navigationScroll.clear();
state.outlineExpanded.clear();
@@ -3843,7 +3840,7 @@ function renderOutlines(reset = true) {
if (outlines.length > 0) {
el.outlineList.append(createOutlineList(outlines));
}
el.pageListPanel.scrollTop = scrollTop;
el.navigationContent.scrollTop = scrollTop;
showNavigation(selected && !selected.hidden ? selected : el.pagesTab);
}
@@ -4162,9 +4159,9 @@ function enablePageDrag(button, index) {
const tick = () => {
if (seq !== state.openSeq || !state.editing) { finish(false); return; }
if (dragging) {
const rect = el.pageListPanel.getBoundingClientRect();
const rect = el.navigationContent.getBoundingClientRect();
const delta = y < rect.top + 48 ? -10 : y > rect.bottom - 48 ? 10 : 0;
if (delta) el.pageListPanel.scrollTop += delta;
if (delta) el.navigationContent.scrollTop += delta;
locate();
}
frame = requestAnimationFrame(tick);
@@ -4286,7 +4283,7 @@ function thumbnailObserver() {
}
trimPageCache();
}, {
root: el.pageListPanel,
root: el.navigationContent,
rootMargin: "180px 0px",
});
}