首先,这个消息聊天框的设计要考虑到:
- 消息的 发出者,接收者
- 消息的状态:已发(用数组保存起来);未发(输入值并获取)
- 手机端键盘弹起的高度对界面内容的展示的影响
第一个问题 消息的 发出者,接收者
这两种角色可以用一组对象完成,用speaker来定义两种角色,通过判断是哪一种角色进行循环遍历他们的消息内容
第三个问题 手机端键盘弹起的高度对界面内容的展示的影响
当键盘弹起时,我们所展示的聊天消息要展示当前的最后一条;所以我们要找到最后一条消息,通过 scroll-into-view 跳转到与其 id名一致的位置(可查看scroll-view的用法),通过为每一种角色数据的循环遍历,确定最后一条数据的位置;将整个页面的高度-键盘的高度=可视化的页面高度;将数据显示在这个可视化页面区域
wxml
<!--pages/message/detail-message/detail-message.wxml-->
<view>
<van-nav-bar left-arrow title="标题" bind:click-left="onClickLeft" />
<view>
<scroll-view scroll-y scroll-into-view='{{toView}}' style='height: {{scrollHeight}};'>
<block wx:key="*this" wx:for='{{msgList}}' wx:for-index="index">
<!-- 单个消息1 客服发出(左) -->
<view wx:if='{{item.speaker=="server"}}' id='msg-{{index}}' class="server">
<view class="see-server">
<image class="avatar" src='../../../icons/profiles/workbench-bg.jpg'>
</image>
</view>
<view class="before-icon">
<image src='../../../icons/message/left.png' mode='widthFix'></image>
</view>
<view class='leftMsg'>{{item.content}}</view>
</view>
<!-- 单个消息2 用户发出(右) -->
<view wx:else id='msg-{{index}}' class="custom">
<view class='rightMsg'>{{item.content}}</view>
<view class="before-icon">
<image src='../../../icons/message/right.png' mode='widthFix'></image>
</view>
<view style='width: 11vw; height: 11vw;'>
<image class="avatar" src='{{picHead}}'></image>
</view>
</view>
</block>
<!-- 占位 -->
<view class="site"></view>
</scroll-view>
<view class='inputRoom' style='bottom: {{inputBottom}}'>
<input
bindconfirm='sendClick'
adjust-position='{{false}}'
value='{{inputVal}}'
confirm-type='send'
bindfocus='focus'
bindblur='blur'
class="send-input"
></input>
</view>
</view>
</view>
js
const app = getApp();
let inputVal = ''; //输入框的内容,未发
let msgList = []; //聊天记录,已发
let windowWidth = wx.getSystemInfoSync().windowWidth; //可使用屏幕宽度
let windowHeight = wx.getSystemInfoSync().windowHeight;//可使用屏幕高度
let keyHeight = 0; //键盘弹起高度
/**
* 初始化数据
*/
function initData(that) {
inputVal = '';
msgList = [
{
speaker: 'server',
contentType: 'text',
content: '我是左边'
},
{
speaker: 'customer',
contentType: 'text',
content: '我是右边'
},
{
speaker: 'server',
contentType: 'text',
content: '左边已经收到右边来的数据'
},
]
that.setData({
msgList,
inputVal
})
}
Page({
/**
* 页面的初始数据
*/
data: {
scrollHeight: '100vh', //这个高度一定要有
inputBottom: 0,
inputVal: '',
picHead: '../../../icons/profiles/avatar.jpg'
},
/**
* 生命周期函数--监听页面加载
*/
onLoad: function (options) {
initData(this);
// this.setData({
// picHead: app.globalData.userInfo.picHead,
// });
},
// 获取聚焦,键盘弹起
focus: function(e) {
keyHeight = e.detail.height;
this.setData({
scrollHeight: (windowHeight - keyHeight) + 'px'
});
this.setData({
toView: 'msg-' + (msgList.length - 1),
inputBottom: keyHeight + 'px'
})
},
//失去聚焦(软键盘消失)
blur: function(e) {
this.setData({
scrollHeight: '100vh',
inputBottom: 0
})
this.setData({
toView: 'msg-' + (msgList.length - 1)
})
},
// 发送点击监听
sendClick: function(e) {
msgList.push({
speaker: 'customer',
contentType: 'text',
content: e.detail.value
})
inputVal = '';
this.setData({
msgList,
inputVal
});
},
// nav栏返回
onClickLeft() {
wx.reLaunch({
url: '/pages/message/message',
})
},
/**
* 生命周期函数--监听页面初次渲染完成
*/
onReady: function () {
},
/**
* 生命周期函数--监听页面显示
*/
onShow: function () {
},
/**
* 生命周期函数--监听页面隐藏
*/
onHide: function () {
},
/**
* 生命周期函数--监听页面卸载
*/
onUnload: function () {
},
/**
* 页面相关事件处理函数--监听用户下拉动作
*/
onPullDownRefresh: function () {
},
/**
* 页面上拉触底事件的处理函数
*/
onReachBottom: function () {
},
/**
* 用户点击右上角分享
*/
onShareAppMessage: function () {
}
})
wxss
page{
background-color: #eee;
}
.van-nav-bar{
padding: 0 !important;
}
.server{
display: flex;
padding: 2vw 11vw 2vw 2vw;
}
.see-server{
width: 11vw;
height: 11vw;
}
.avatar{
width: 11vw;
height: 11vw;
border-radius: 10rpx;
}
.before-icon{
position: relative;
width: 4vw;
height: 11vw;
margin-left: 0.5vw;
display: flex;
align-items: center;
z-index: 9;
}
.before-icon image{
width: 4vw;
}
.custom{
display: flex;
justify-content: flex-end;
padding: 2vw 2vw 2vw 11vw;
}
.inputRoom {
width: 100vw;
height: 16vw;
border-top: 1px solid #cdcdcd;
background-color: #f1f1f1;
padding-left: 50rpx;
position: fixed;
bottom: 0;
display: flex;
align-items: center;
z-index: 20;
}
input {
width: 76vw;
height: 9.33vw;
background-color: #fff;
border-radius: 40rpx;
margin-left: 2vw;
padding: 0 3vw;
font-size: 28rpx;
color: #444;
}
.leftMsg {
font-size: 35rpx;
color: #444;
line-height: 7vw;
padding: 2vw 2.5vw;
background-color: #fff;
margin-left: -1.6vw;
border-radius: 10rpx;
z-index: 10;
}
.rightMsg {
font-size: 35rpx;
color: #444;
line-height: 7vw;
padding: 2vw 2.5vw;
background-color: #96EB6A;
margin-right: -1.6vw;
border-radius: 10rpx;
z-index: 10;
}
.site{
width: 100%;
height: 18vw;
}
.footer{
width: 7vw;
margin-left: 3.2vw;
}
转载于:https://blog.csdn.net/java558/article/details/86001064?utm_source=distribute.pc_relevant.none-task