fix: 聊天页面默认在最底部
This commit is contained in:
@@ -597,6 +597,7 @@ export default {
|
||||
scrollViewHeight: 0, // 滚动视图高度
|
||||
oldScrollViewHeight: 0, // 加载历史消息前的滚动高度
|
||||
scrollViewStyle: '', // 动态设置 scroll-view 高度样式
|
||||
currentScrollPosition: 0, // 仅用于内部记录位置,不绑定到 view
|
||||
|
||||
// 分页相关
|
||||
page: 1,
|
||||
@@ -712,25 +713,25 @@ export default {
|
||||
this.$nextTick(() => {
|
||||
const systemInfo = uni.getSystemInfoSync();
|
||||
const windowHeight = systemInfo.windowHeight; // 窗口高度(px)
|
||||
|
||||
|
||||
// 使用 uni.createSelectorQuery 获取头部和底部的高度
|
||||
const query = uni.createSelectorQuery().in(this);
|
||||
|
||||
|
||||
// 查询头部高度
|
||||
query.select('.chat-header').boundingClientRect((headerRect) => {
|
||||
const headerHeight = headerRect ? headerRect.height : 0;
|
||||
|
||||
|
||||
// 查询底部高度
|
||||
const query2 = uni.createSelectorQuery().in(this);
|
||||
query2.select('.chat-footer').boundingClientRect((footerRect) => {
|
||||
const footerHeight = footerRect ? footerRect.height : 0;
|
||||
|
||||
|
||||
// 计算 scroll-view 的可用高度
|
||||
const scrollHeight = windowHeight - headerHeight - footerHeight;
|
||||
|
||||
|
||||
// 设置样式(使用 px 单位,因为系统信息返回的是 px)
|
||||
this.scrollViewStyle = `height: ${scrollHeight}px;`;
|
||||
|
||||
|
||||
console.log('Scroll-view height calculated:', {
|
||||
windowHeight,
|
||||
headerHeight,
|
||||
@@ -747,7 +748,13 @@ export default {
|
||||
* 记录当前滚动位置
|
||||
*/
|
||||
onScroll(e) {
|
||||
this.scrollTop = e.detail.scrollTop;
|
||||
// >>>>>>>>>> 修复的核心改动 >>>>>>>>>>
|
||||
// 移除: this.scrollTop = e.detail.scrollTop;
|
||||
// 原因: 实时将滚动位置赋值回绑定了 :scroll-top 的变量,会导致 scroll-view
|
||||
// 在用户触摸时不断尝试"矫正"位置,从而引发画面抽搐。
|
||||
// 只需记录位置供内部逻辑使用即可,不要去更新绑定的属性。
|
||||
|
||||
this.currentScrollPosition = e.detail.scrollTop;
|
||||
},
|
||||
|
||||
/**
|
||||
@@ -858,13 +865,6 @@ export default {
|
||||
}
|
||||
},
|
||||
|
||||
/**
|
||||
* 监听新消息事件
|
||||
*/
|
||||
/**
|
||||
* 监听新消息事件
|
||||
* 优化:只在用户不在滚动时才自动滚动到底部
|
||||
*/
|
||||
/**
|
||||
* 监听新消息事件
|
||||
*/
|
||||
@@ -928,18 +928,18 @@ export default {
|
||||
const mSenderId = m.sender_user_id || '';
|
||||
const messageSenderId = message.sender_user_id || '';
|
||||
if (mSenderId !== messageSenderId) return false;
|
||||
|
||||
|
||||
// 比较消息内容(标准化后比较)
|
||||
const mContent = normalizeContent(m.message_content || m.content || '');
|
||||
const messageContent = normalizeContent(message.message_content || message.content || '');
|
||||
if (mContent !== messageContent) return false;
|
||||
|
||||
|
||||
// 时间戳匹配(放宽到30秒,处理网络延迟)
|
||||
const mTime = m.created_at || m.timestamp || 0;
|
||||
const messageTime = message.created_at || message.timestamp || 0;
|
||||
return Math.abs(mTime - messageTime) < 30000; // 30秒
|
||||
});
|
||||
|
||||
|
||||
if (tempMessageIndex !== -1) {
|
||||
// 找到临时消息,用服务器返回的消息替换
|
||||
this.messages[tempMessageIndex] = message;
|
||||
@@ -953,16 +953,16 @@ export default {
|
||||
const messageContent = normalizeContent(message.message_content || message.content || '');
|
||||
const senderId = message.sender_user_id || '';
|
||||
const messageTime = message.created_at || message.timestamp || 0;
|
||||
|
||||
|
||||
const existingIndexByContent = this.messages.findIndex(m => {
|
||||
const mContent = normalizeContent(m.message_content || m.content || '');
|
||||
const mSenderId = m.sender_user_id || '';
|
||||
const mTime = m.created_at || m.timestamp || 0;
|
||||
|
||||
|
||||
// 内容相同(标准化后)、发送者相同、时间差在30秒内
|
||||
return mContent === messageContent &&
|
||||
mSenderId === senderId &&
|
||||
Math.abs(mTime - messageTime) < 30000; // 放宽到30秒
|
||||
return mContent === messageContent &&
|
||||
mSenderId === senderId &&
|
||||
Math.abs(mTime - messageTime) < 30000; // 放宽到30秒
|
||||
});
|
||||
|
||||
if (existingIndexByContent !== -1) {
|
||||
@@ -1280,7 +1280,7 @@ export default {
|
||||
// 先清空 scroll-into-view,避免与 scroll-top 冲突
|
||||
// 注意:不清空 scrollTop,避免重置滚动位置
|
||||
this.scrollIntoView = '';
|
||||
|
||||
|
||||
this.$nextTick(() => {
|
||||
// 等待 DOM 更新
|
||||
setTimeout(() => {
|
||||
@@ -1297,7 +1297,7 @@ export default {
|
||||
scrollToOldLastMessage() {
|
||||
// 先清空 scroll-into-view,避免优先级冲突
|
||||
this.scrollIntoView = '';
|
||||
|
||||
|
||||
this.$nextTick(() => {
|
||||
// 使用 uni.createSelectorQuery 获取准确的滚动高度
|
||||
const query = uni.createSelectorQuery().in(this);
|
||||
|
||||
Reference in New Issue
Block a user