详解微信小程序实现仿微信聊天界面(各种细节处理)


Posted in Javascript onFebruary 17, 2019

本文介绍了微信小程序实现仿微信聊天界面,分享给大家,具体如下:

下面先来看看效果

详解微信小程序实现仿微信聊天界面(各种细节处理)

为实现这样的效果,首先要解决两个问题:

1.点击输入框弹出软键盘后,将已有的少许聊天内容弹出,导致看不到的问题;

2.键盘弹出或收起时,聊天消息没有自动滚到最底部。

首先解决第二个问题,自动滚动到最底部,这很简单,这里提供三种方法(推荐第三种):

1.计算每条消息的最大高度,设置scroll-top=(单条msg最大高度 * msg条数)px。

2.用 将展示msg的目标scroll-view包裹,

通过js获取到该view的实际高度:

var that = this;
var query = wx.createSelectorQuery();
query.select('.scrollMsg').boundingClientRect(function(rect) {
	that.setData({
		scrollTop: rect.height+'px';
	});
}).exec();

3.(推荐)将所有msg都编号如:msg-0,msg-1,msg-2… 直接锁定最后一条msg,滚动到那里。

  • 在scroll-view中添加:scroll-into-view='{{toView}}'
  • 在wx:for后面添加:wx:for-index="index"
  • 在每个msg布局中添加:id='msg-{{index}}'

最后直接:

this.setData({
	toView: 'msg-' + (msgList.length - 1)
})

到这里第二个问题解决了,那么我们回过来解决第一个问题:

(点击输入框弹出软键盘后,将已有的少许聊天内容弹出,导致看不到的问题)

1.首先我们需要将input的自动向上推给关掉,这里有个坑:

在input组件中添加:adjust-position='{{false}}'

而不是:adjust-position='false'

这么做虽然不再向上推,但却导致了软键盘弹起时,会遮挡屏幕下部分的消息。

2.如何解决软键盘弹起时,会遮挡屏幕下部分的消息?

当软键盘弹起时,将scroll-view的高度缩短至软键盘遮挡不到的屏幕上方部分,当软键盘收起时,再将scroll-view的高度还原,这样解决了遮挡问题。

提示:

input中的bindfocus='focus'可获取软键盘高度并监听软键盘弹起,bindblur='blur'可监听软键盘收起,var windowHeight = wx.getSystemInfoSync().windowHeight;可获得屏幕高度。

scrollHeight(滚动条高度) = windowHeight(屏幕高度) - 软键盘高度;

最后将input组件放在软键盘上面就完成了。

各位要不要代码?

contact.js:

// pages/contact/contact.js
const app = getApp();
var inputVal = '';
var msgList = [];
var windowWidth = wx.getSystemInfoSync().windowWidth;
var windowHeight = wx.getSystemInfoSync().windowHeight;
var keyHeight = 0;

/**
 * 初始化数据
 */
function initData(that) {
 inputVal = '';

 msgList = [{
   speaker: 'server',
   contentType: 'text',
   content: '欢迎来到英雄联盟,敌军还有30秒到达战场,请做好准备!'
  },
  {
   speaker: 'customer',
   contentType: 'text',
   content: '我怕是走错片场了...'
  }
 ]
 that.setData({
  msgList,
  inputVal
 })
}

/**
 * 计算msg总高度
 */
// function calScrollHeight(that, keyHeight) {
//  var query = wx.createSelectorQuery();
//  query.select('.scrollMsg').boundingClientRect(function(rect) {
//  }).exec();
// }

Page({

 /**
  * 页面的初始数据
  */
 data: {
  scrollHeight: '100vh',
  inputBottom: 0
 },

 /**
  * 生命周期函数--监听页面加载
  */
 onLoad: function(options) {
  initData(this);
  this.setData({
   cusHeadIcon: app.globalData.userInfo.avatarUrl,
  });
 },

 /**
  * 生命周期函数--监听页面显示
  */
 onShow: function() {

 },

 /**
  * 页面相关事件处理函数--监听用户下拉动作
  */
 onPullDownRefresh: function() {

 },

 /**
  * 页面上拉触底事件的处理函数
  */
 onReachBottom: function() {

 },

 /**
  * 获取聚焦
  */
 focus: function(e) {
  keyHeight = e.detail.height;
  this.setData({
   scrollHeight: (windowHeight - keyHeight) + 'px'
  });
  this.setData({
   toView: 'msg-' + (msgList.length - 1),
   inputBottom: keyHeight + 'px'
  })
  //计算msg高度
  // calScrollHeight(this, keyHeight);

 },

 //失去聚焦(软键盘消失)
 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
  });


 },

 /**
  * 退回上一页
  */
 toBackClick: function() {
  wx.navigateBack({})
 }

})

contact.wxml:

<!--pages/contact/contact.wxml-->

<view>

 <scroll-view scroll-y scroll-into-view='{{toView}}' style='height: {{scrollHeight}};'>
  <!-- <view class='scrollMsg'> -->
  <block wx:key wx:for='{{msgList}}' wx:for-index="index">

   <!-- 单个消息1 客服发出(左) -->
   <view wx:if='{{item.speaker=="server"}}' id='msg-{{index}}' style='display: flex; padding: 2vw 11vw 2vw 2vw;'>
    <view style='width: 11vw; height: 11vw;'>
     <image style='width: 11vw; height: 11vw; border-radius: 10rpx;' src='../../images/contact_member.png'></image>
    </view>
    <view style='width: 4vw; height: 11vw; margin-left: 0.5vw; display: flex; align-items: center; z-index: 9;'>
     <image style='width: 4vw;' src='../../images/left_msg.png' mode='widthFix'></image>
    </view>
    <view class='leftMsg'>{{item.content}}</view>
   </view>

   <!-- 单个消息2 用户发出(右) -->
   <view wx:else id='msg-{{index}}' style='display: flex; justify-content: flex-end; padding: 2vw 2vw 2vw 11vw;'>
    <view class='rightMsg'>{{item.content}}</view>
    <view style='width: 4vw; height: 11vw; margin-right: 0.5vw; display: flex; align-items: center; z-index: 9;'>
     <image style='width: 4vw;' src='../../images/right_msg.png' mode='widthFix'></image>
    </view>
    <view style='width: 11vw; height: 11vw;'>
     <image style='width: 11vw; height: 11vw; border-radius: 10rpx;' src='{{cusHeadIcon}}'></image>
    </view>
   </view>

  </block>
  <!-- </view> -->

  <!-- 占位 -->
  <view style='width: 100%; height: 18vw;'></view>
 </scroll-view>

 <view class='inputRoom' style='bottom: {{inputBottom}}'>
  <image style='width: 7vw; margin-left: 3.2vw;' src='../../images/pic_icon.png' mode='widthFix'></image>
  <input bindconfirm='sendClick' adjust-position='{{false}}' value='{{inputVal}}' confirm-type='send' bindfocus='focus' bindblur='blur'></input>
 </view>
</view>

contact.wxss:

/* pages/contact/contact.wxss */

page {
 background-color: #f1f1f1;
}

.inputRoom {
 width: 100vw;
 height: 16vw;
 border-top: 1px solid #cdcdcd;
 background-color: #f1f1f1;
 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;
}

以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持三水点靠木。

Javascript 相关文章推荐
对frameset、frame、iframe的js操作示例代码
Aug 16 Javascript
纯javascript实现的小游戏《Flappy Pig》实例
Jul 27 Javascript
jquery实现九宫格大转盘抽奖
Nov 13 Javascript
JavaScript数组去重的两种方法推荐
Apr 05 Javascript
浅谈js中调用函数时加不加括号的问题
Jul 28 Javascript
DWR3 访问WEB元素的两种方法实例详解
Jan 03 Javascript
jquery easyui dataGrid动态改变排序字段名的方法
Mar 02 Javascript
解决angular双向绑定无效果,ng-model不能正常显示的问题
Oct 02 Javascript
ES6知识点整理之函数数组参数的默认值及其解构应用示例
Apr 17 Javascript
JS如何定义用字符串拼接的变量
Jul 11 Javascript
在antd4.0中Form使用initialValue操作
Nov 02 Javascript
Antd-vue Table组件添加Click事件,实现点击某行数据教程
Nov 17 Javascript
JavaScript遍历DOM元素的常见方式示例
Feb 16 #Javascript
原生JS实现逼真的图片3D旋转效果详解
Feb 16 #Javascript
JS实现简单的抽奖转盘效果示例
Feb 16 #Javascript
mocha的时序规则讲解
Feb 16 #Javascript
jQuery实现ajax的嵌套请求案例分析
Feb 16 #jQuery
解决微信小程序中转换时间格式IOS不兼容的问题
Feb 15 #Javascript
详解Element 指令clickoutside源码分析
Feb 15 #Javascript
You might like
ThinkPHP实现动态包含文件的方法
2014/11/29 PHP
利用switch语句进行多选一判断的实例代码
2016/11/14 PHP
php正则表达式使用方法整理集合
2020/01/31 PHP
出现“不能执行已释放的Script代码”错误的原因及解决办法
2007/08/29 Javascript
浅析webapp框架AngularUI的demo
2014/12/21 Javascript
jQuery中click事件用法实例
2014/12/26 Javascript
jQuery中:nth-child选择器用法实例
2014/12/31 Javascript
javascript强制点击广告的方法
2015/02/06 Javascript
javascript十六进制及二进制转化的方法
2015/05/06 Javascript
详解JavaScript的while循环的使用
2015/06/03 Javascript
JavaScript中Date对象的常用方法示例
2015/10/24 Javascript
HTML5 Shiv完美解决IE(IE6/IE7/IE8)不兼容HTML5标签的方法
2015/11/25 Javascript
javascript基本数据类型及类型检测常用方法小结
2016/12/14 Javascript
如何使用angularJs
2017/05/08 Javascript
纯js实现的积木(div层)拖动功能示例
2017/07/19 Javascript
Webpack优化配置缩小文件搜索范围
2017/12/25 Javascript
CKeditor4 字体颜色功能配置方法教程
2019/06/26 Javascript
[55:16]Mski vs VGJ.S Supermajor小组赛C组 BO3 第二场 6.3
2018/06/04 DOTA
Python素数检测的方法
2015/05/11 Python
在Pandas中处理NaN值的方法
2019/06/25 Python
使用Python合成图片的实现代码(图片添加个性化文本,图片上叠加其他图片)
2020/04/30 Python
初学者学习Python好还是Java好
2020/05/26 Python
Python3 ffmpeg视频转换工具使用方法解析
2020/08/10 Python
汤米巴哈马官方网站:Tommy Bahama
2017/05/13 全球购物
JACK & JONES瑞典官方网站:杰克琼斯欧式风格男装
2017/12/23 全球购物
ZWILLING双立人法国网上商店:德国刀具锅具厨具品牌
2019/08/28 全球购物
Fabletics官网:美国运动服饰品牌,由好莱坞女演员凯特·哈德森创立
2019/10/19 全球购物
计算机通信专业推荐信
2014/02/22 职场文书
初三学习决心书
2014/03/11 职场文书
社区文艺活动方案
2014/08/19 职场文书
庆国庆活动总结
2014/08/28 职场文书
2015年社区科普工作总结
2015/05/13 职场文书
MySQL如何构建数据表索引
2021/05/13 MySQL
Pytorch 如何加速Dataloader提升数据读取速度
2021/05/28 Python
Python Pygame实战之塔防游戏的实现
2022/03/17 Python
windows10 家庭版下FTP服务器搭建教程
2022/08/05 Servers