im-聊天框的滚动条置底
在做即使通信遇到一个需求,需要将滚动条置底,记录一下解决方法
核心代码
<div class="list" ref="list">
...
</div>
<script setup>
const list = ref(null)
// 滚动到底部
const scrollListToButtom = () => {
nextTick(() => {
let listNode = list.value
if (!listNode) {
return
}
// 元素内容垂直滚动的像素数 = 元素内容高度
listNode.scrollTop = listNode.scrollHeight
})
}
</script>
此时,只要触发 scrollListToButtom
方法即可将滚动条置底
当用户切换会话列表或发送消息时,触发scrollListToButtom
,但是当切换会话触发scrollListToButtom
时,获取到的 listNode.scrollHeight 不是节点真正的scrollHeight,而是可视范围内的高度。
解决办法:写在生命周期updated可以完美解决
写在updated,我们可以不用通过发送或切换会话触发scrollListToButtom
,只需要将scrollListToButtom
方法写进updated即可。
bug:如果消息中有动态加载的图片,会出现不触底的情况
onUpdated(() => {
scrollMessageListToButtom()
// 这里需要先执行触底函数,然后再执行一次触底函数
// 第一次执行是因为用户切换会话列表,立刻执行触底,滚动条会显示在底部
// 但是如果有图片未加载完成,scrollHeight是获取不到的,当图片加载完成时,滚动条位置就会有偏差,所以就需要第二次执行
// 第二次执行的目的时等待图片加载完成,最简单的是我们可以用定时器延迟一秒再加载来解决
// setTimeout(() => {
// scrollMessageListToButtom()
// }, 1000);
// 最好的处理方法是监控img加载完毕事件,再调用触底函数,如下:
})
const imageLoaded = computed(() => store.state.conversation.imageLoaded)
watch(imageLoaded, () => {
scrollMessageListToButtom()
})
// 图片添加@load="onImageLoaded"
<img @load="onImageLoaded" />
// 监听图片加载完成事件
const onImageLoaded = (event) => {
store.commit('conversation/updateImageLoaded', event)
}
完美解决!
遇到的小bug:
一开始我对scrollTop设置值时,总是设置失败,返回0,后来发现是我布局的问题,简单来说就是因为我给一个没有滚动条的元素设置滚动条的位置,导致我无法设置scrollTop。 什么时候存在滚动条? 父子DIV是嵌套关系时,子DIV高度大于父DIV时,且overflow:auto,就会出现滚动条,若overflow:hidden,超出部分被隐藏,也不会出现滚动条。注意:滚动条是属于父DIV的
补充知识点:修改滚动条样式
.list::-webkit-scrollbar {
width: 10px;
height: 10px;
/**/
}
.list::-webkit-scrollbar-thumb {
background: #444;
border-radius: 10px;
}
.list::-webkit-scrollbar-thumb:hover {
background: #333;
}