© 2024 Merano Tu. All rights reserved.
Merano Tu
2024/7/12
因為工作上的需求,寫了個 chatbot 功能,在寫到『需隨時滾動到最新訊息』的這部分時好好地思索了一下。
本文只有 『需隨時滾動到最新訊息』 的解法
以下三種跟上最新訊息的方式分享給大家,也是我自己嘗試的進程,
最後一個是我最後採用的方式
使用 JavaScript 控制,使用 scrollIntoView
抓取容器內最後一個元素,並讓這個元素滑動至畫面中。
使用 behavior: "smooth"
讓 scroll 順順地滑~
每新增一個新訊息, 呼叫 scrolltoChatBottom()
一次
const scrolltoChatBottom = () => {
var lastChild = container.lastElementChild;
lastChild.scrollIntoView({ behavior: "smooth" });
};
是否過於頻繁呼叫導致效能堪憂?
每發一個訊息就會執行一次滑動 😵💫
文字 array 順序反向,使用 column-reverse 讓資料流呈現反向,就可以用純 css 的方式達成了!完全不用 js 來動態處理
想到這種方式的人真的很強:
原創的詳細版的解說在這
打造聊天框丝滑滚动体验:AI 聊天框的翻转之道-腾讯云开发者社区-腾讯云 (tencent.com)
.content {
height: 100%;
overflow-y: auto;
display: flex;
flex-direction: column-reverse;
}
並用 新增一個占位元素(來使出初始訊息未滿整個畫面時置頂,而非貼底)
// 他會填滿畫面未滿的空間,直到畫面已滿他就會把自我縮小~
.occupied {
flex-grow: 1;
flex-shrink: 1;
background-color: #fff; //跟底色同色
}
唯一小缺點是,如果出現下一則訊息時,你的視窗不是滾動到對話的最底部時,就會從此無法自動跟上對話 TAT
所以!為了效能以及萬無一失的跟上最新訊息,我決定結合前兩種方法!
使用以下 js + 方法2的 css
// 這裡的 js 主要是補足 方法2 的小缺點,檢查最新訊息不在範圍內時才會執行滾動
// 這可以讓這 function 被執行的次數比例少很多
const scrolltoChatBottom = () => {
var lastChild = container.firstElementChild;
var bottom = lastChild.getBoundingClientRect().top;
// 檢查元素的底部是否在視口中
if (bottom > window.innerHeight) {
// 如果元素的底部不在視口中,則滾動到該元素
lastChild.scrollIntoView({ behavior: "smooth" });
}
};
希望大家看得懂,我代表不休息的 chatbot 下台一鞠躬