fix(plugin-md-power): fix mark lazy animation, close #789 (#791)

This commit is contained in:
pengzhanbo 2025-12-12 20:41:09 +08:00 committed by GitHub
parent 95d345bf6d
commit a350e62645
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194

View File

@ -1,12 +1,10 @@
import { onBeforeUnmount, onMounted } from 'vue'
import { onContentUpdated, useRouter } from 'vuepress/client'
import { onContentUpdated } from 'vuepress/client'
const MARK_MODE_ATTR = 'data-mark-mode'
const MARK_MODE_LAZY = 'lazy'
const MARK_VISIBLE_CLASS = 'vp-mark-visible'
const MARK_BOUND_ATTR = 'data-vp-mark-bound'
const MARK_SELECTOR = '.vp-doc mark'
const DOC_SELECTOR = '.vp-doc'
const MARK_SELECTOR = 'mark'
const BOUND_SELECTOR = `${MARK_SELECTOR}[${MARK_BOUND_ATTR}="1"]`
export function setupMarkHighlight(mode: 'lazy' | 'eager'): void {
@ -23,9 +21,7 @@ export function setupMarkHighlight(mode: 'lazy' | 'eager'): void {
root.setAttribute(MARK_MODE_ATTR, MARK_MODE_LAZY)
let intersectionObserver: IntersectionObserver | null = null
let mutationObserver: MutationObserver | null = null
let rafId: number | null = null
let removeAfterEach: (() => void) | null = null
const ensureObserver = () => {
if (!intersectionObserver) {
@ -75,66 +71,21 @@ export function setupMarkHighlight(mode: 'lazy' | 'eager'): void {
})
}
const observeDocMutations = () => {
const doc = document.querySelector(DOC_SELECTOR)
if (!doc)
const resetObserver = () => {
if (!intersectionObserver)
return
if (mutationObserver)
mutationObserver.disconnect()
intersectionObserver.disconnect()
intersectionObserver = null
mutationObserver = new MutationObserver((mutations) => {
if (mutations.some(mutation => mutation.addedNodes.length > 0))
scheduleBind()
})
mutationObserver.observe(doc, { childList: true, subtree: true })
}
const resetObserver = () => {
document.querySelectorAll<HTMLElement>(BOUND_SELECTOR).forEach((mark) => {
Array.from(document.querySelectorAll<HTMLElement>(BOUND_SELECTOR) || []).forEach((mark) => {
if (!mark.classList.contains(MARK_VISIBLE_CLASS))
mark.removeAttribute(MARK_BOUND_ATTR)
})
if (intersectionObserver) {
intersectionObserver.disconnect()
intersectionObserver = null
}
}
const router = useRouter()
onMounted(() => {
observeDocMutations()
scheduleBind()
})
onContentUpdated(() => {
resetObserver()
observeDocMutations()
scheduleBind()
})
if (router?.afterEach) {
removeAfterEach = router.afterEach(() => {
resetObserver()
observeDocMutations()
scheduleBind()
})
}
if (router?.isReady) {
router.isReady().then(() => scheduleBind()).catch(() => {})
}
onBeforeUnmount(() => {
if (rafId !== null)
cancelAnimationFrame(rafId)
resetObserver()
mutationObserver?.disconnect()
mutationObserver = null
removeAfterEach?.()
removeAfterEach = null
})
}