|
@@ -514,30 +514,20 @@ function getTocBullet(level) {
|
|
|
return bullets[Math.min(level - 1, bullets.length - 1)]
|
|
return bullets[Math.min(level - 1, bullets.length - 1)]
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
-// 规范化文本(移除多余空格、特殊字符)
|
|
|
|
|
-function normalizeText(text) {
|
|
|
|
|
- if (!text) return ''
|
|
|
|
|
- return text
|
|
|
|
|
- .replace(/\s+/g, ' ') // 多个空格变一个
|
|
|
|
|
- .replace(/[\u00A0]/g, ' ') // 不间断空格转普通空格
|
|
|
|
|
- .trim()
|
|
|
|
|
-}
|
|
|
|
|
-
|
|
|
|
|
-// 滚动到指定章节(通过标题元素匹配)
|
|
|
|
|
|
|
+// 滚动到指定章节(只匹配 h1-h6 标题元素)
|
|
|
function scrollToHeading(item) {
|
|
function scrollToHeading(item) {
|
|
|
- const titleText = normalizeText(item.title || item.text)
|
|
|
|
|
|
|
+ const titleText = (item.title || item.text || '').trim()
|
|
|
if (!titleText) return
|
|
if (!titleText) return
|
|
|
|
|
|
|
|
// 在文档内容区域中查找标题元素
|
|
// 在文档内容区域中查找标题元素
|
|
|
const editorContent = document.querySelector('.editor-content')
|
|
const editorContent = document.querySelector('.editor-content')
|
|
|
if (!editorContent) return
|
|
if (!editorContent) return
|
|
|
|
|
|
|
|
- // 1. 先查找 h1-h6 标题元素
|
|
|
|
|
|
|
+ // 查找 h1-h6 标题元素
|
|
|
const headings = editorContent.querySelectorAll('h1, h2, h3, h4, h5, h6')
|
|
const headings = editorContent.querySelectorAll('h1, h2, h3, h4, h5, h6')
|
|
|
|
|
|
|
|
- // 精确匹配
|
|
|
|
|
for (const heading of headings) {
|
|
for (const heading of headings) {
|
|
|
- const headingText = normalizeText(heading.textContent)
|
|
|
|
|
|
|
+ const headingText = heading.textContent?.trim()
|
|
|
if (headingText === titleText) {
|
|
if (headingText === titleText) {
|
|
|
heading.scrollIntoView({ behavior: 'smooth', block: 'start' })
|
|
heading.scrollIntoView({ behavior: 'smooth', block: 'start' })
|
|
|
highlightElement(heading)
|
|
highlightElement(heading)
|
|
@@ -545,40 +535,6 @@ function scrollToHeading(item) {
|
|
|
}
|
|
}
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
- // 包含匹配(标题包含目录文本,或目录文本包含标题)
|
|
|
|
|
- for (const heading of headings) {
|
|
|
|
|
- const headingText = normalizeText(heading.textContent)
|
|
|
|
|
- if (headingText && (headingText.includes(titleText) || titleText.includes(headingText))) {
|
|
|
|
|
- heading.scrollIntoView({ behavior: 'smooth', block: 'start' })
|
|
|
|
|
- highlightElement(heading)
|
|
|
|
|
- return
|
|
|
|
|
- }
|
|
|
|
|
- }
|
|
|
|
|
-
|
|
|
|
|
- // 2. 如果 h1-h6 没找到,尝试查找带粗体样式的段落(可能是标题)
|
|
|
|
|
- const boldSpans = editorContent.querySelectorAll('span[style*="font-weight:bold"], strong, b')
|
|
|
|
|
- for (const span of boldSpans) {
|
|
|
|
|
- const spanText = normalizeText(span.textContent)
|
|
|
|
|
- if (spanText === titleText || spanText.includes(titleText) || titleText.includes(spanText)) {
|
|
|
|
|
- const parent = span.closest('p, div, h1, h2, h3, h4, h5, h6') || span
|
|
|
|
|
- parent.scrollIntoView({ behavior: 'smooth', block: 'start' })
|
|
|
|
|
- highlightElement(parent)
|
|
|
|
|
- return
|
|
|
|
|
- }
|
|
|
|
|
- }
|
|
|
|
|
-
|
|
|
|
|
- // 3. 最后尝试全文搜索
|
|
|
|
|
- const allElements = editorContent.querySelectorAll('p, div, span')
|
|
|
|
|
- for (const el of allElements) {
|
|
|
|
|
- const elText = normalizeText(el.textContent)
|
|
|
|
|
- // 检查元素直接包含的文本(不是子元素的文本)
|
|
|
|
|
- if (elText === titleText) {
|
|
|
|
|
- el.scrollIntoView({ behavior: 'smooth', block: 'start' })
|
|
|
|
|
- highlightElement(el)
|
|
|
|
|
- return
|
|
|
|
|
- }
|
|
|
|
|
- }
|
|
|
|
|
-
|
|
|
|
|
ElMessage.info(`章节「${titleText}」在当前文档中不存在`)
|
|
ElMessage.info(`章节「${titleText}」在当前文档中不存在`)
|
|
|
}
|
|
}
|
|
|
|
|
|