---
# System prepended metadata

title: '[前端] 自動滑到聊天室最底部的方式'

---

因為工作上的需求，寫了個 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 下台一鞠躬