feat: 处理消息发送之后的页面滚动问题
This commit is contained in:
@@ -83,8 +83,8 @@ import userAvatar from '@assets/images/login/user_icon.png';
|
||||
import aiAvatar from '@assets/images/login/blue_logo.png';
|
||||
|
||||
|
||||
///(控制滚动位置)
|
||||
const scrollTop = ref(99999);
|
||||
// 列表滚动容器引用
|
||||
const listRef = ref<HTMLElement | null>(null);
|
||||
|
||||
/// 会话列表
|
||||
const chatMsgList = ref<ChatMessage[]>([]);
|
||||
@@ -93,8 +93,8 @@ const inputMessage = ref("");
|
||||
/// 发送消息中标志
|
||||
const isSendingMessage = ref(false);
|
||||
|
||||
/// agentId 首页接口中获取
|
||||
const agentId = ref("1953462165250859010");
|
||||
/// agentId 首页接口中获取 1953462165250859010
|
||||
const agentId = ref("1");
|
||||
/// 会话ID 历史数据接口中获取
|
||||
const conversationId = ref("");
|
||||
// 会话进行中标志
|
||||
@@ -123,15 +123,39 @@ const sleep = (ms: number) => new Promise((res) => setTimeout(res, ms));
|
||||
// 当前会话的消息ID,用于保持发送和终止的messageId一致
|
||||
let currentSessionMessageId: string | null = null;
|
||||
|
||||
// 滚动到底部 - 优化版本,确保打字机效果始终可见
|
||||
const scrollToBottom = () => {
|
||||
// 滚动到底部 - 精确计算 last 元素位置并使用双 rAF 保证布局稳定
|
||||
const scrollToBottom = (smooth = false) => {
|
||||
nextTick(() => {
|
||||
// 使用更大的值确保滚动到真正的底部
|
||||
scrollTop.value = 99999;
|
||||
// 强制触发滚动更新,增加延迟确保DOM更新完成
|
||||
setTimeout(() => {
|
||||
scrollTop.value = scrollTop.value + Math.random();
|
||||
}, 10);
|
||||
const el = listRef.value;
|
||||
if (!el) return;
|
||||
|
||||
const doScroll = () => {
|
||||
const last = el.lastElementChild as HTMLElement | null;
|
||||
// 计算容器 style padding-bottom,保证滚动到真正可视底部
|
||||
const style = window.getComputedStyle(el);
|
||||
const paddingBottom = parseFloat(style.paddingBottom || '0') || 0;
|
||||
|
||||
if (last) {
|
||||
const lastOffset = last.offsetTop + last.offsetHeight;
|
||||
const target = lastOffset + paddingBottom - el.clientHeight;
|
||||
const top = Math.max(0, Math.ceil(target));
|
||||
if (smooth && typeof el.scrollTo === 'function') {
|
||||
el.scrollTo({ top, behavior: 'smooth' });
|
||||
} else {
|
||||
el.scrollTop = top;
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
// 兜底:滚到底
|
||||
if (smooth && typeof el.scrollTo === 'function') {
|
||||
el.scrollTo({ top: el.scrollHeight, behavior: 'smooth' });
|
||||
} else {
|
||||
el.scrollTop = el.scrollHeight;
|
||||
}
|
||||
};
|
||||
// 使用两次 requestAnimationFrame 增强在复杂渲染/打字机更新场景的可靠性
|
||||
requestAnimationFrame(() => requestAnimationFrame(doScroll));
|
||||
});
|
||||
};
|
||||
|
||||
@@ -388,6 +412,7 @@ const handleWebSocketMessage = (data: any) => {
|
||||
isSessionActive.value = false;
|
||||
// 清理当前会话的 messageId,避免保留陈旧 id
|
||||
resetMessageState();
|
||||
setTimeoutScrollToBottom();
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
Reference in New Issue
Block a user