vue 仿app聊天室
分析
- 当收到新消息时,消息层自动滚动
- 当查看聊天记录时,禁止消息层滚动
- 键盘弹出/收起 的时候,消息层滚动到最新消息处
使用到vue的技术点
html 结构
1 | <transition-group tag="ul" name="slide" class="barrage-container" |
js 实现
1、首先要先初始化,获取当前包裹消息的父类container
,和显示区域containerParentH
的高度,获取containerParentH
是为了后面计算消息层滚动到底部需要的距离
1
2
3
4__init () {
this.container = $('.barrage-container')
this.containerParentH = this.container.parent().height()
}
2、列表过渡钩子函数实现
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25//-----------
// 这里只用到了进入中的钩子函数
//-----------
// 节点进入前,在这个函数里可以设置进入前的样式,比如随机字体颜色,随机位置等。
beforeEnter (el) {
// el.style.cssText = `color:${this.colorRandom()}`
},
// 此回调函数是可选项的设置
// 与 CSS 结合时使用
// 主要是进入过程的样式,如果是横屏滚动弹幕 可以设置滚动的速度
enter: function (el, done) {
done() // 必须调用,表示进入过程已经完成,才能触发afterEnter函数
},
// 节点进入后
// 需要scrollTop的距离
afterEnter: function (el) {
const insertDomH = el.offsetHeight //获取当前插入节点的高度
this.containerH += insertDomH // 累加插入节点的高度containerH,主要是为了计算消息层滚动到底部
this.scroll(insertDomH) // 消息滚动到底部或不滚动
},
3、获取消息层滚动到底部的距离
1
2
3
4
5// 获取滚动到底部要滚动的距离
scrollBottomY () {
const Y = this.containerH - this.containerParentH // 当前所有插入节点的高度和 - 显示消息区域的高度
return Y > 0 ? Y : 0 // 当消息层高度没有高出显示区域 滚动距离是0
},
4、消息层滚动到底部
1
2
3
4
5
6// 滚动到底部
scrollBottom () {
this.scrollTop = this.scrollBottomY() // 获取滚动到底部要滚动的距离 并记录当前滚动的距离
this.container.scrollTop(this.scrollTop) // 滚动到相应位置
return this.scrollTop
},
5、滚动
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17// 滚动
//
// 这快主要是判断当前是否处于查看聊天记录状态,是,禁止消息层自动滚动。反之,滚
// 动。
//
scroll (insertDomH) {
// this.scrollBottomY() - this.getScrollTop() - insertDomH
// 如果是插入节点前消息已经滚动到底部 得到的值 是 0.
// 判断条件 > 40 主要留个容忍值。
// 即:插入节点前差消息层 40~0 距离滚动到底部。收到新消息也允许消息层自动滚动
if (this.scrollBottomY() - this.getScrollTop() - insertDomH > 40) {
return false
} else {
this.scrollBottom()
}
},
6、这里我使用定时器模拟了接受新消息
1
2
3
4
5
6
7
8
9
10
11mounted () {
this.$nextTick(() => {
this.__init() // 初始化
// 模拟数据
let index = 0
setInterval(() => {
this.barrageList.push({message: `的煎熬几个好啊和耦合个熊恶化${index}`, self: false, nickName: '爱你所爱', headSrc: '../../static/head/ic_head10@2x.png'})
index++
}, 2000)
})
}
至此,大部分功能已经实现。接下来就是自己发送一条消息情况下的一些交互实现
7、首先实现,真实事件(input: 获取 / 失去焦点 )触发消息层滚动到底部的代码
1
2
3
4
5// 手动触发滚动底部
scrollBottomHook () {
this.containerParentH = this.container.parent().height() // 重新计算消息层显示区域的高度
this.scrollBottom() // 滚动到底部
}
8、失去/获取 焦点 调用的函数
1
2
3
4
5
6
7
8// 手动触发弹幕滚动到底部
// 此函数实现的是父类中调用 聊天室组件的 scrollDownHook() 方法
barrageScrollBottom () {
this.barrage ? false : (this.barrage = this.$refs.barrage)
setTimeout(() => {
this.barrage.scrollDownHook()
}, 500) // 加个定时器的原因主要是,键盘弹出 收起 有延迟的原因
}