聊天记录滚动锚定的实现

1. 开始

有个项目需要用到IM聊天功能,在向上翻更多聊天记录时,需要将位置固定,也就是加载更多时不要滚动到顶部,也不要跳动、抖动。

尝试了n种方法,终于可以了,这里记录下。

2. 尝试方案

2.1. overflow-anchor

尝试用css自带属性overflow-anchor: auto解决这一问题,但是它的兼容性太差了,在chrome、开发者工具中调试的效果可以,但是真机小程序、H5都不行。

此外,这一属性需要scrollTop不能为0,也就是在插入数据之前检查下scrollTop,如果为0,则调用API让scroll-view向下滚动一点。

2.2. 赋值前将scrollY设置为false

这种方式是想在list添加前将scroll-view固定,然后在前面插入数据,想法是挺好的,但是一插入数据,scroll-view还是滚动到了顶部,也就是scroll-view内部是让scroll-top在插入数据前后不变。

2.3. 赋值后立即设置scrollTop

这种方式是想在数据插入后立即滚动到原来的位置,H5是没问题的,小程序不可以,因为小程序设置scrollTop是异步的,list一旦赋值,并传递到渲染层就渲染了,这时候再改变scrollTop,或设置scrollInfoView会导致页面抖动。

2.4. 赋值后立即调用scrollInfoView

无效的原因与上相同。

3. 解决方法

3.1. scroll-view倒置

采用的是scroll-view倒置,列表数据也倒置,这样每次加载下一页,可以当成是普通listloadMore,从而解决跳动的问题。

scss 复制代码
.press-message-detail {
  transform: rotate(180deg);

  .press-message-item {
    transform: rotate(180deg);
  }
}

调用者无需关心list的翻转,由组件内部处理:

ts 复制代码
export default {
  computed: {
    reversedList() {
      const res = [
        ...this.list,
      ];
      res.reverse();
      return res;
    },
  },
}

3.2. 隐藏scrollbar

同时要注意隐藏scrollbar,因为scrollbar此时跑到了左边。用下面的方式在小程序中无效,采用的是Dom覆盖的方式。

scss 复制代码
::-webkit-scrollbar {
  display: none;
  width: 0;
  height: 0;
  color: transparent;
}

3.3. 数据少的情况

此外,当聊天内容不足一屏时,消息是堆在下面的,因为scroll-view被倒置了。

解决方案是,设置一个placeholderdom,设置为flex:1,让它和消息内容共享父容器的高度。

4. 体验地址

目前在press-ui示例项目中可以查看效果,三端(H5、微信小程序、QQ小程序)表现一致。

另外,欢迎使用press-ui跨端组件库。

5. 资料

网上被这一问题困扰的人还挺多的,这是我查阅资料时看到的一部分:

  1. developers.weixin.qq.com/community/d...
  2. developers.weixin.qq.com/community/d...
  3. developers.weixin.qq.com/community/d...
  4. developers.weixin.qq.com/community/d...
  5. developers.weixin.qq.com/community/d...
  6. developers.weixin.qq.com/community/d...
相关推荐
用户693717500138442 分钟前
Google 正在“收紧侧加载”:陌生 APK 安装或需等待 24 小时
android·前端
蓝帆傲亦1 小时前
Web 前端搜索文字高亮实现方法汇总
前端
用户69371750013841 小时前
Room 3.0:这次不是升级,是重来
android·前端·google
漫随流水2 小时前
旅游推荐系统(view.py)
前端·数据库·python·旅游
踩着两条虫3 小时前
VTJ.PRO 核心架构全公开!从设计稿到代码,揭秘AI智能体如何“听懂人话”
前端·vue.js·ai编程
jzlhll1234 小时前
kotlin Flow first() last()总结
开发语言·前端·kotlin
蓝冰凌5 小时前
Vue 3 中 defineExpose 的行为【defineExpose暴露ref变量】详解:自动解包、响应性与实际使用
前端·javascript·vue.js
奔跑的呱呱牛5 小时前
generate-route-vue基于文件系统的 Vue Router 动态路由生成工具
前端·javascript·vue.js
柳杉6 小时前
从动漫水面到赛博飞船:这位开发者的Three.js作品太惊艳了
前端·javascript·数据可视化