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