From 2417dd974dc20c074d728e78823192f17cff7f97 Mon Sep 17 00:00:00 2001 From: cwchen <1048842385@qq.com> Date: Tue, 11 Nov 2025 09:43:28 +0800 Subject: [PATCH] =?UTF-8?q?=E9=80=89=E4=B8=AD=E8=83=8C=E6=99=AF=E8=89=B2?= =?UTF-8?q?=E4=BC=98=E5=8C=96?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/views/common/DocumentSearch.vue | 95 ++++++++++++++++++++--------- 1 file changed, 66 insertions(+), 29 deletions(-) diff --git a/src/views/common/DocumentSearch.vue b/src/views/common/DocumentSearch.vue index c47b9b7..a3a46b1 100644 --- a/src/views/common/DocumentSearch.vue +++ b/src/views/common/DocumentSearch.vue @@ -3,7 +3,8 @@
- + 搜索 @@ -217,7 +218,7 @@ export default { const placeholder = document.createElement('div') placeholder.className = 'pdf-page placeholder' placeholder.style.margin = '0px auto 10px' - placeholder.style.position= 'relative'; + placeholder.style.position = 'relative'; placeholder.dataset.page = pageNumber placeholder.dataset.status = 'placeholder' fragment.appendChild(placeholder) @@ -541,8 +542,8 @@ export default { console.error('全文预处理失败', error) } } - - + + this.highlightMatches() } finally { this.searching = false @@ -728,7 +729,7 @@ export default { if (!skipNavigate) { this.navigateToResult(this.currentResultIndex, true) } else { - this.updateCurrentResultActiveState() + this.scheduleActiveHighlightRefresh() } }, @@ -749,7 +750,7 @@ export default { } this.currentResultIndex = index - this.updateCurrentResultActiveState() + this.scheduleActiveHighlightRefresh() const target = this.searchResults[this.currentResultIndex]?.element if (!target) return @@ -842,22 +843,48 @@ export default { this.searchResults[matchIndex].element = elements[0] || null }) - this.updateCurrentResultActiveState() + this.scheduleActiveHighlightRefresh() }, updateCurrentResultActiveState() { + const activePageContainers = new Set() + this.searchResults.forEach((item, idx) => { if (!item) return const elements = item.elements && item.elements.length ? item.elements : item.element ? [item.element] : [] elements.forEach((el) => { if (!el) return if (idx === this.currentResultIndex) { - el.classList.add('is-active') + el.classList.add('is-active', 'is-current') + const container = el.closest('.pdf-page') + if (container) { + activePageContainers.add(container) + } } else { - el.classList.remove('is-active') + el.classList.remove('is-active', 'is-current') } }) }) + + this.pageContainers.forEach((container) => { + if (!container) return + container.classList.remove('has-active-match') + }) + activePageContainers.forEach((container) => { + container.classList.add('has-active-match') + }) + }, + + scheduleActiveHighlightRefresh() { + this.$nextTick(() => { + if (typeof window !== 'undefined' && window.requestAnimationFrame) { + window.requestAnimationFrame(() => { + this.updateCurrentResultActiveState() + }) + } else { + this.updateCurrentResultActiveState() + } + }) }, goToPrevious() { @@ -955,11 +982,11 @@ export default { this.observer = new IntersectionObserver((entries) => { entries.forEach((entry) => { if (entry.isIntersecting) { - const page = Number(entry.target.dataset.page) - if (page) { - this.renderTextLayer(page, { visible: true, force: true }) - this.scheduleRender(page, { priority: true }) - } + const page = Number(entry.target.dataset.page) + if (page) { + this.renderTextLayer(page, { visible: true, force: true }) + this.scheduleRender(page, { priority: true }) + } } else { const page = Number(entry.target.dataset.page) if (page) { @@ -978,15 +1005,15 @@ export default { initial.forEach((container) => { const page = Number(container.dataset.page) if (page) { - if (page === 1) { - // 已在预处理中完成 - return - } - if (page <= this.initialPreloadedCount) { - this.scheduleRender(page, { priority: true }) - } else { - this.scheduleRender(page) - } + if (page === 1) { + // 已在预处理中完成 + return + } + if (page <= this.initialPreloadedCount) { + this.scheduleRender(page, { priority: true }) + } else { + this.scheduleRender(page) + } } }) }, @@ -1008,8 +1035,8 @@ export default { .document-search { display: flex; flex-direction: column; - height: calc(100vh - 84px); - overflow: hidden; + height: calc(100vh - 84px); + overflow: hidden; background: #f4f7ff; padding: 16px; box-sizing: border-box; @@ -1171,19 +1198,20 @@ export default { 0% { transform: rotate(0deg); } + 100% { transform: rotate(360deg); } } -.pdf-page > canvas.pdf-canvas { +.pdf-page>canvas.pdf-canvas { position: relative; top: 0; left: 50%; transform: translateX(-50%); } -.pdf-page > .textLayer { +.pdf-page>.textLayer { position: absolute; top: 0; left: 50%; @@ -1196,9 +1224,18 @@ export default { border-radius: 2px; } -.search-highlight.is-active { - background: rgba(32, 109, 255, 0.85); +::v-deep .search-highlight.is-active, +::v-deep .search-highlight.is-current { + background: #206dff !important; color: #ffffff; + box-shadow: 0 0 0 2px rgba(32, 109, 255, 0.35); + border-radius: 4px; + transition: background 0.2s ease, box-shadow 0.2s ease; +} + +.pdf-page.has-active-match { + box-shadow: 0 0 0 3px rgba(32, 109, 255, 0.45), 0 12px 36px rgba(32, 109, 255, 0.18); + transition: box-shadow 0.3s ease; } .state-panel {