聊天对话框项目的几点思考
前端比划
共 2328字,需浏览 5分钟
·
2024-06-06 21:48
近一周,原来同事拉着帮忙做了一个聊天的小项目,主要是和后端这边对接聊天室的接口和前端交互。
收发消息通过webSocket浏览器原生接口就行,API很简单。保持ws连接活跃,需要实现心跳消息重连等操作。
功能界面大概就是这样,能够发送文字、图片、表情,和自定义的名片信息。
1、用户聊天信息如何分列呈现?
首先实现是同一用户的消息保持在同一列,用户变了后,消息在另一侧展示,如此反复。于是大概是这样的。
第一页时,第一条或当前消息的发送者和上一条消息的发送者相同时,保持在同侧,否则切换。
往前翻阅消息时,分页数据由后往前推,即由分页最后一条消息与消息列表已有的最前一条消息比较是否由同人发送。
calcPosChatMsgs() {
let previousId = null, //初始化上一个ID变量
prevActive = true,
isNeedCalcNums = this.isNeedCalcNums,
newMsgs = [],
isSiblingActive;
//重置为初始状态
this.isNeedCalcNums = 0;
if(isNeedCalcNums) {
newMsgs = this.chatMessageList.slice(0, isNeedCalcNums).reverse();
//往前下页的数据以它后面第一条数据的状态为基准
isSiblingActive = this.chatMessageList[isNeedCalcNums].isActive;
previousId = this.chatMessageList[isNeedCalcNums].user_info.user_id;
newMsgs = newMsgs.map(function (item, index) {
if(item.user_info.user_id == previousId) {
item.isActive = isSiblingActive;
}else {
item.isActive = !isSiblingActive;
isSiblingActive = !isSiblingActive;
}
previousId = item.user_info.user_id;
return item;
}).reverse();
return newMsgs.concat(...this.chatMessageList.slice(isNeedCalcNums));
}
return this.chatMessageList.map(function (item, index) {
if(index === 0 || item.user_info.user_id == previousId) {
if(item.isActive === undefined) {
item.isActive = prevActive;
}else {
prevActive = item.isActive;
}
}else {
if(item.isActive === undefined) {
item.isActive = !prevActive;
prevActive = !prevActive;
}else {
prevActive = item.isActive;
}
}
previousId = item.user_info.user_id;
return item;
});
}
后面需求方查看后,感觉不对,“提出用户自身的消息保持在右侧,其他人的消息左侧显示”,应该和微信类似。大道至简,一语点破的感觉,固定位置还有了某种意义上的归属和确定感。
2、消息随着对话次数的增加,加载历史分页数据会不会导致重复消息的渲染呢?
如果是基于消息实时数量分页的话,简单分页可能就会出问题了。基于此,前端在将数据添加至消息列表中时,可先做一个去重操作;同时并不信任第一页数据中返回的总页数,并以此作为是否允许加载下一页的依据。
PS:这里等消息在页面上渲染完成后,手动将滚动条往下移了部分位置,往上自动加载下一页时,继续等待用户的行为来触发。
评论