word 搜索优化
This commit is contained in:
parent
48dd413f87
commit
5be02d46fd
|
|
@ -176,6 +176,33 @@ export default {
|
|||
return (element.textContent || '').trim()
|
||||
},
|
||||
|
||||
getSearchableTextContent(element) {
|
||||
if (!element) return ''
|
||||
let text = ''
|
||||
const walker = document.createTreeWalker(
|
||||
element,
|
||||
NodeFilter.SHOW_TEXT,
|
||||
{
|
||||
acceptNode: (node) => {
|
||||
const parent = node.parentElement
|
||||
if (!parent) return NodeFilter.FILTER_REJECT
|
||||
const tagName = parent.tagName ? parent.tagName.toLowerCase() : ''
|
||||
if (tagName === 'mark' || tagName === 'script' || tagName === 'style' || tagName === 'noscript') {
|
||||
return NodeFilter.FILTER_REJECT
|
||||
}
|
||||
return NodeFilter.FILTER_ACCEPT
|
||||
}
|
||||
}
|
||||
)
|
||||
let node
|
||||
while ((node = walker.nextNode())) {
|
||||
if (node.textContent) {
|
||||
text += node.textContent
|
||||
}
|
||||
}
|
||||
return text
|
||||
},
|
||||
|
||||
prepareSearchSegments(forceReset = false) {
|
||||
if (!this.docRendered) {
|
||||
if (forceReset) {
|
||||
|
|
@ -270,7 +297,7 @@ export default {
|
|||
highlightTextInNode(node, pattern, results, segmentIndex, parentElement, markIndexRef) {
|
||||
if (node.nodeType === Node.TEXT_NODE) {
|
||||
const text = node.textContent
|
||||
if (!text || !text.trim()) return
|
||||
if (!text) return
|
||||
|
||||
pattern.lastIndex = 0
|
||||
const textMatches = []
|
||||
|
|
@ -355,17 +382,9 @@ export default {
|
|||
|
||||
const results = []
|
||||
let totalTextMatches = 0
|
||||
const segmentMatchCounts = []
|
||||
|
||||
this.searchSegments.forEach((el, segmentIndex) => {
|
||||
const originalText = el.dataset.originalText
|
||||
if (typeof originalText === 'undefined' || !originalText) return
|
||||
|
||||
pattern.lastIndex = 0
|
||||
const textMatchCount = (originalText.match(pattern) || []).length
|
||||
if (textMatchCount === 0) return
|
||||
|
||||
totalTextMatches += textMatchCount
|
||||
|
||||
const originalHtml = el.dataset.originalHtml
|
||||
if (typeof originalHtml === 'undefined') return
|
||||
|
||||
|
|
@ -373,25 +392,47 @@ export default {
|
|||
el.innerHTML = cleanHtml
|
||||
el.dataset.originalHtml = cleanHtml
|
||||
|
||||
const searchableText = this.getSearchableTextContent(el)
|
||||
if (!searchableText) return
|
||||
|
||||
pattern.lastIndex = 0
|
||||
const textMatchCount = (searchableText.match(pattern) || []).length
|
||||
if (textMatchCount === 0) return
|
||||
|
||||
totalTextMatches += textMatchCount
|
||||
|
||||
const existingMarks = el.querySelectorAll('mark')
|
||||
if (existingMarks.length > 0) {
|
||||
console.warn(`Segment ${segmentIndex} still has ${existingMarks.length} mark tags after cleaning`)
|
||||
}
|
||||
|
||||
const markIndexRef = { value: 0 }
|
||||
const beforeHighlightText = this.getSearchableTextContent(el)
|
||||
const children = Array.from(el.childNodes)
|
||||
children.forEach(child => {
|
||||
this.highlightTextInNode(child, pattern, results, segmentIndex, el, markIndexRef)
|
||||
})
|
||||
|
||||
const createdMarks = el.querySelectorAll('mark.search-highlight')
|
||||
if (createdMarks.length !== textMatchCount) {
|
||||
console.warn(`Segment ${segmentIndex}: expected ${textMatchCount} marks, created ${createdMarks.length}`)
|
||||
const actualCount = createdMarks.length
|
||||
const afterHighlightText = this.getSearchableTextContent(el)
|
||||
|
||||
segmentMatchCounts.push({
|
||||
segmentIndex,
|
||||
expected: textMatchCount,
|
||||
actual: actualCount,
|
||||
searchableTextLength: searchableText.length,
|
||||
beforeHighlightLength: beforeHighlightText.length,
|
||||
afterHighlightLength: afterHighlightText.length
|
||||
})
|
||||
|
||||
if (actualCount !== textMatchCount) {
|
||||
console.warn(`Segment ${segmentIndex}: expected ${textMatchCount} marks, created ${actualCount}. Text: "${searchableText.substring(0, 100)}..."`)
|
||||
}
|
||||
})
|
||||
|
||||
if (results.length !== totalTextMatches) {
|
||||
console.warn(`Total matches mismatch: expected ${totalTextMatches}, got ${results.length}`)
|
||||
console.warn(`Total matches mismatch: expected ${totalTextMatches}, got ${results.length}`, segmentMatchCounts)
|
||||
}
|
||||
|
||||
this.searchResults = results
|
||||
|
|
|
|||
Loading…
Reference in New Issue