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 {