fix: sync post scroller with window

This commit is contained in:
Tim
2025-08-05 19:39:13 +08:00
parent 82c0aa240a
commit 7fe37d0131

View File

@@ -3,7 +3,7 @@
<div v-if="isWaitingFetchingPost" class="loading-container"> <div v-if="isWaitingFetchingPost" class="loading-container">
<l-hatch size="28" stroke="4" speed="3.5" color="var(--primary-color)"></l-hatch> <l-hatch size="28" stroke="4" speed="3.5" color="var(--primary-color)"></l-hatch>
</div> </div>
<div v-else class="post-page-main-container" ref="mainContainer" @scroll="onScroll"> <div v-else class="post-page-main-container" ref="mainContainer">
<div class="article-title-container"> <div class="article-title-container">
<div class="article-title-container-left"> <div class="article-title-container-left">
<div class="article-title">{{ title }}</div> <div class="article-title">{{ title }}</div>
@@ -170,6 +170,7 @@ export default {
onBeforeUnmount(() => { onBeforeUnmount(() => {
document.title = defaultTitle document.title = defaultTitle
if (metaDescriptionEl) metaDescriptionEl.setAttribute('content', defaultDescription) if (metaDescriptionEl) metaDescriptionEl.setAttribute('content', defaultDescription)
window.removeEventListener('scroll', updateCurrentIndex)
}) })
const lightboxVisible = ref(false) const lightboxVisible = ref(false)
@@ -202,12 +203,12 @@ export default {
const items = [] const items = []
if (mainContainer.value) { if (mainContainer.value) {
const main = mainContainer.value.querySelector('.info-content-container') const main = mainContainer.value.querySelector('.info-content-container')
if (main) items.push({ el: main, top: 0 }) if (main) items.push({ el: main, top: getTop(main) })
for (const c of comments.value) { for (const c of comments.value) {
const el = document.getElementById('comment-' + c.id) const el = document.getElementById('comment-' + c.id)
if (el) { if (el) {
items.push({ el, top: getTopRelativeTo(el, mainContainer.value) }) items.push({ el, top: getTop(el) })
} }
} }
// 根据 top 排序,防止评论异步插入后顺序错乱 // 根据 top 排序,防止评论异步插入后顺序错乱
@@ -230,11 +231,8 @@ export default {
parentUserName: parentUserName parentUserName: parentUserName
}) })
const getTopRelativeTo = (el, container) => { const getTop = (el) => {
const elRect = el.getBoundingClientRect() return el.getBoundingClientRect().top + window.scrollY
const parentRect = container.getBoundingClientRect()
// 加上 scrollTop得到相对于 container 内部顶部的距离
return elRect.top - parentRect.top + container.scrollTop
} }
const findCommentPath = (id, list) => { const findCommentPath = (id, list) => {
@@ -336,19 +334,16 @@ export default {
async () => { async () => {
await nextTick() await nextTick()
gatherPostItems() gatherPostItems()
updateCurrentIndex()
} }
) )
const updateCurrentIndex = () => { const updateCurrentIndex = () => {
const container = mainContainer.value const scrollTop = window.scrollY
if (!container) return
const scrollTop = container.scrollTop
for (let i = 0; i < postItems.value.length; i++) { for (let i = 0; i < postItems.value.length; i++) {
const el = postItems.value[i] const el = postItems.value[i]
// 计算元素相对 container 顶部的 top const top = getTop(el)
const top = getTopRelativeTo(el, container)
const bottom = top + el.offsetHeight const bottom = top + el.offsetHeight
if (bottom > scrollTop) { if (bottom > scrollTop) {
@@ -362,9 +357,9 @@ export default {
const index = Number(e.target.value) const index = Number(e.target.value)
currentIndex.value = index currentIndex.value = index
const target = postItems.value[index - 1] const target = postItems.value[index - 1]
if (target && mainContainer.value) { if (target) {
const top = getTopRelativeTo(target, mainContainer.value) const top = getTop(target)
mainContainer.value.scrollTo({ top, behavior: 'instant' }) window.scrollTo({ top, behavior: 'instant' })
} }
} }
@@ -591,6 +586,7 @@ export default {
await fetchPost() await fetchPost()
if (id) expandCommentPath(id) if (id) expandCommentPath(id)
updateCurrentIndex() updateCurrentIndex()
window.addEventListener('scroll', updateCurrentIndex)
await jumpToHashComment() await jumpToHashComment()
}) })
@@ -613,7 +609,6 @@ export default {
postId, postId,
postComment, postComment,
onSliderInput, onSliderInput,
onScroll: updateCurrentIndex,
copyPostLink, copyPostLink,
subscribePost, subscribePost,
unsubscribePost, unsubscribePost,