From f25713828304dd2b72c35698dc9f536eb7e1126e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E4=B8=80=E6=96=B9=E7=9A=84=E8=B5=9B=E5=8D=9A=E7=9C=9F?= =?UTF-8?q?=E5=90=9B?= Date: Thu, 22 Jan 2026 11:08:57 +0800 Subject: [PATCH] fix(chat): prevent auto-scroll from overriding user scroll When users scroll up to view earlier content in the chat, the auto-scroll timer would keep pulling them back to the bottom. This was caused by the restart condition incorrectly triggering when users were not at the bottom. Changes: - Add userScrolledAway flag to track when user scrolls away from bottom - Stop auto-scroll timer when user scrolls away - Only restart auto-scroll when user manually scrolls back to bottom - Simplify threshold calculation with isNearBottom variable --- frontend/src/views/chat/index.vue | 27 ++++++++++++++++----------- 1 file changed, 16 insertions(+), 11 deletions(-) diff --git a/frontend/src/views/chat/index.vue b/frontend/src/views/chat/index.vue index d8067172..d57c1805 100644 --- a/frontend/src/views/chat/index.vue +++ b/frontend/src/views/chat/index.vue @@ -569,6 +569,8 @@ let scrollTime: any let scrollingTime: any let scrollTopVal = 0 let scrolling = false +let userScrolledAway = false // 用户是否主动滚动离开底部 + const scrollBottom = () => { if (scrolling) return if (!isTyping.value && !getRecommendQuestionsLoading.value) { @@ -588,22 +590,25 @@ const handleScroll = (val: any) => { scrollingTime = setTimeout(() => { scrolling = false }, 400) - if ( - scrollTopVal + 200 < - innerRef.value!.clientHeight - (document.querySelector('.chat-record-list')!.clientHeight - 20) - ) { + + const threshold = + innerRef.value!.clientHeight - + (document.querySelector('.chat-record-list')!.clientHeight - 20) + const isNearBottom = scrollTopVal + 50 >= threshold + + // 用户滚动离开底部时,标记并停止自动滚动 + if (!isNearBottom) { + userScrolledAway = true clearInterval(scrollTime) scrollTime = null return } - if ( - !scrollTime && - isTyping.value && - scrollTopVal + 30 < - innerRef.value!.clientHeight - - (document.querySelector('.chat-record-list')!.clientHeight - 20) - ) { + // 用户滚回底部时,重置标记 + userScrolledAway = false + + // 只有用户在底部、没有主动滚走、且正在输入时才启动自动滚动 + if (!scrollTime && isTyping.value && !userScrolledAway) { scrollTime = setInterval(() => { scrollBottom() }, 300)