文章目录

  • 前言
  • 思路
  • 代码实现

前言

上一篇讲到了如何布局,这一篇将讲一下如何用uni-app实现小程序聊天页面的最主要的功能——发消息后页面滚动到最底部(参考过很多文章最后找到比较适合的方法)。

其他的功能(参考微信),之后的文章会讲述到具体实现方法

  • 点击聊天框的时候,聊天框随键盘抬起且聊天消息列表滚动到最底部,但整体页面不抬起
  • 聊天框textarea根据内容自适应高度,且聊天消息列表随着聊天框的增高而滚动到最底部(说白了就是最底部的消息不会被增高的聊天框给挡住)

思路

由于我们在布局上聊天滚动用的是scroll-view,里面嵌套着一个存放消息列表的容器(如左图所示),scroll-view中的一个重要属性是scroll-top,官方文档解释设置竖向滚动条位置

当消息列表的长度超过scroll-view的高度时,它们之间的高度差就是scroll-view要滚动的距离(如右图所示)。

获取节点信息用boundingClientRect这个函数,具体方法可以参考官网uni.createSelectorQuery() | uni-app官网 (dcloud.net.cn)

原本js部分的代码是这样写的:

scrollToBottom(){let query = uni.createSelectorQuery().in(this);// 获取节点信息query.select('#scrollview').boundingClientRect();query.select('#msglistview').boundingClientRect();query.exec((res) =>{if(res[1].height > res[0].height){this.scrollTop = res[1].height - res[0].height}})
},

但是,在实测时(小程序模拟器和真机)发现滚动的位置有时滚动不到最底部(如图所示,其实下面还有一条消息被遮住了没显示出来),有时又可以滚动到最底部。

初步怀疑是节点信息获取不准确,我就去搜了关于boundingClientRect()这个函数的相关信息,官方文档上并没有对这个问题的解释,后来找到解决方案

参考文章:微信小程序 boundingClientRect 获取元素节点位置信息不准确_LGDmar的博客-CSDN博客

问题所在:页面未渲染完成而去获取了节点信息

解决方案

方法一:可以设置一个延时函数setTimeout,因为我们不知道渲染的时间是多少,所以我是经过试验得出一个满足需求的延时时间。

// 滚动至聊天底部
scrollToBottom(){// 外层加一个延时函数是为了能获取到节点的准确信息setTimeout(()=>{let query = uni.createSelectorQuery().in(this);// 获取节点信息query.select('#scrollview').boundingClientRect();query.select('#msglistview').boundingClientRect();query.exec((res) =>{if(res[1].height > res[0].height){this.scrollTop = this.rpxTopx(res[1].height - res[0].height)}})},15)
},

方法二:

使用$nextTick,意为在下次DOM更新完之后执行一个回调函数。

//滚动至聊天底部
scrollToBottom(){let query = uni.createSelectorQuery().in(this);//获取节点信息query.select('#scrollview').boundingClientRect();query.select('#msglistview').boundingClientRect();query.exec((res) =>{if(res[1].height > res[0].height){this.$nextTick(()=>{this.scrollTop = this.rpxTopx(res[1].height - res[0].height)})}})
},

代码实现

vue页面:
(如果需要参考css部分,请看我发布的上篇文章布局篇)

<template><view class="chat"><scroll-view  :style="{height: `${windowHeight}rpx`}"id="scrollview"scroll-y="true" :scroll-top="scrollTop":scroll-with-animation="true"class="scroll-view"><!-- 聊天主体 --><view id="msglistview" class="chat-body"><!-- 聊天记录 --><view v-for="(item,index) in msgList" :key="index"><!-- 自己发的消息 --><view class="item self" v-if="item.userContent != ''" ><!-- 文字内容 --><view class="content right">{{item.userContent}}</view><!-- 头像 --><view class="avatar"></view></view><!-- 机器人发的消息 --><view class="item Ai" v-if="item.botContent != ''"><!-- 头像 -->     <view class="avatar"></view><!-- 文字内容 --><view class="content left">{{item.botContent}}</view></view></view></view></scroll-view><!-- 底部消息发送栏 --><!-- 用来占位,防止聊天消息被发送框遮挡 --><view class="chat-bottom"><view class="send-msg"><view class="uni-textarea"><textarea v-model="chatMsg"maxlength="300":show-confirm-bar="false"auto-height></textarea></view><button @click="handleSend" class="send-btn">发送</button></view></view></view>
</template>
<script>export default {data() {return {//滚动距离scrollTop: 0,userId:'',//发送的消息chatMsg:"",msgList:[{botContent: "hello,请问我有什么可以帮助你的吗?",recordId: 0,titleId: 0,userContent: "",userId: 0},{botContent: "",recordId: 0,titleId: 0,userContent: "你好呀我想问你一件事",userId: 0},] }},computed: {windowHeight() {return this.rpxTopx(uni.getSystemInfoSync().windowHeight)}},methods: {// px转换成rpxrpxTopx(px){let deviceWidth = wx.getSystemInfoSync().windowWidthlet rpx = ( 750 / deviceWidth ) * Number(px)return Math.floor(rpx)},//滚动至聊天底部scrollToBottom(){//外层加一个延时函数是为了能获取到节点的准确信息setTimeout(()=>{let query = uni.createSelectorQuery().in(this);//获取节点信息query.select('#scrollview').boundingClientRect();query.select('#msglistview').boundingClientRect();query.exec((res) =>{if(res[1].height > res[0].height){this.scrollTop = this.rpxTopx(res[1].height - res[0].height)}})},15)},// 发送消息handleSend() {//如果消息不为空if(!this.chatMsg||!/^\s+$/.test(this.chatMsg)){let obj = {botContent: "",recordId: 0,titleId: 0,userContent: this.chatMsg,userId: 0}this.msgList.push(obj);this.chatMsg = '';}else {this.$modal.showToast('不能发送空白消息')}},}}
</script>

【uni-app】uni-app实现聊天页面功能——功能篇(上)相关推荐

  1. 小程序(十六)小程序仿微信聊天页面及功能

    后期打算在小程序中添加即时聊天的功能,但是目前这个还没有考虑好以一种什么样的形势去实现,先接入一个腾讯AI提供的免费闲聊接口.先做一个大概的页面及功能. 腾讯AI地址: https://ai.qq.c ...

  2. IM 聊天页面下拉加载更多--类似微信顺滑展示

    背景     领导在会议上说我们的 IM 聊天页面的用户体验不太好,尤其是下拉加载更多会跳动,让我优化一下.之前还确实没有注意到这一点,现场拿出手机和微信做对比,不比不知道,一比还真是发现了问题.微信 ...

  3. 从APP跳转到微信指定联系人聊天页面功能的实现与采坑之旅

    起因: 最近做的APP中有一个新功能:已知用户微信号,可点击直接跳转到当前用户微信聊天窗口页面. 当时第一想法是使用无障碍来做,并且觉得应该不难,只是逻辑有点复杂.没想到最终踩了好多坑,特地把踩过的坑 ...

  4. 【Android 小功能】启动 App 时实现启动页、引导页功能,并且只在第一次启动 App 时跳入引导页面

    [Android]如何实现启动APP时引导页.欢迎页功能之(一)引导页功能的实现 [Android]如何实现启动APP时引导页.欢迎页功能设置之(二)设置只在第一次启动APP时跳入引导界面

  5. vue整合uniapp_uni-app仿微信App界面|vue+uniapp聊天室|仿微信朋友圈

    项目简介 基于uni-app+vue+vuex+uniPop+swiper等技术开发的仿微信聊天室uniapp-chatroom项目,类似vue及小程序api语法使开发更加方便,实现了发送图文消息.表 ...

  6. uniapp 打包H5,打包小程序,打包app分享到微信聊天、朋友圈

    1.uniapp打包H5操作手法:Hbuilder->发行->网站-PC-WEB端或手机端H5访问,需要填写个访问域名,即发布后访问的域名路径 2.uniapp打包H5配置注意事项:uni ...

  7. 【uni-app】uni-app实现聊天页面功能——功能篇(下)

    目录 前言 一.聊天框随键盘抬起 思路 代码实现 二.聊天消息列表随着聊天框的增高而滚动到最底部 思路 三.问题 完整代码实现 总结 前言 前面我有写关于如何进行聊天页面布局和实现聊天消息滚动到最底部 ...

  8. 直播APP源代码之如何搭建红包秒杀功能

    直播APP源代码之如何搭建红包秒杀功能 yaf项目快速开发(兼容php7): yaf project rapid development, integration of the db action c ...

  9. react native 实现浏览器唤醒APP并跳转指定页面

    推荐使用react-navigation导航器提供的Deep linking 功能来实现. 根据官方的例子来一步步实现: 假设我们要实现在浏览器上通过点击URI(mychat://chat/Eric) ...

最新文章

  1. js base64 解码
  2. 在wamp 2.0环境下面安装Zend Optimizer的方法
  3. npm package.json那些事
  4. Linux入门(6)——Ubuntu16.04安装atom
  5. 动画原理——绘制正弦函数环绕运动椭圆运动
  6. N1CTF 塞题vote分析
  7. Java的Class类文件结构及基本字节码指令
  8. 什么叫大数据人物画像_大数据时代,如何构建精准用户画像,直击精细化运营...
  9. Bootstrap 插件的事件
  10. cadence 常见pcb电阻_高速PCB培训手记
  11. java 日期for循环_java for循环的时候增加循环体的长度是不是不太好的?
  12. Leetcode每日一题:10.09.sorted-matrix-search-lcci(排序矩阵查找)
  13. 【原创】设计模式面对面之观察者模式
  14. HDU 2531 (BFS搜索)
  15. LINUX打包并下载到本地
  16. 即将截止?四川省2022年工业领域大企业大集团跨越发展激励项目申报条件、材料、要求及流程
  17. Python中的shape[0]、shape[1]和shape[-1]分别是什么意思(附代码)
  18. Excel表格中输入一个姓,就可以选择输入需要的姓名了
  19. java控制台实现的简易计算器,实现加减乘除
  20. Python -- 手动搭建HTTP服务器

热门文章

  1. 超详细的 DNS 协议解析
  2. PYQT5安装时,labelImg执行pyrcc5 -o libs/resources.py resources.qrc 报错:File does not exist ‘resources.qrc‘
  3. 中国企业软件公司的转型之路
  4. 如何查找oracle中的服务器端口号,客户端端口号,监听端口及号Enterprise Manager Console HTTP 端口
  5. 跨境12V汽车一键启动PKE无钥匙进入遥控远程启动系统改装
  6. java web 常见框架
  7. 基于Linux的信息处理板卡,linux硬件信息查看
  8. python浏览器怎么设置_如何用python控制浏览器
  9. 雨 霖 铃 【鉴赏】
  10. XMap 简易的Java-xml映射工具类库