让DIV的滚动条(内容)自动滚动到最底部,包含使用vue框架的区别。

在我的移动端页面需要做一个固定高度的DIV,每次往这个DIV中增加内容的时候我需要将滚动条自动滚动至最底部保证每次看到的都是最新的内容。(这样增加了用户的体验度好感,就像微信的聊天窗口一样。)我利用了JavaScript中的scrollTop = scrollHeight这两个属性来实现,代码如下:

html代码:

<div class="box" style="width:500px;height:100px; border:1px solid black;overflow-x: hidden;overflow-y: auto;margin:50px auto 0;padding: 3px;"></div>
<button onclick="add()" style="display:block;width:100px;height:20px;margin:20px auto;">添加</button>

JavaScript代码:

<script>
       function add(){
           var div = document.getElementsByClassName('box')[0];
           var time = new Date().getTime();
           div.innerHTML += `<div>当前时间:${time}</div>`;
           div.scrollTop = div.scrollHeight;
       }
</script>

按照以上思路每次都能如愿的让滚动条滑动至最底部:

可是我使用vue框架的时候就不好使了,每次滚动条没有滑动到最底部,而是底部还有一条信息被隐藏了,很是恼火!

html代码:

<div class="app">
     <div ref="box" class="box" style="width:500px;height:100px; border:1px solid black;overflow-x: hidden;overflow-y: auto;margin:50px auto 0;padding: 3px;">
          <div v-for="item in items">当前时间:{{item.time}}</div>
      </div>
      <button @click="add" style="display:block;width:100px;height:20px;margin:20px auto;">添加</button>
</div>

JavaScript代码:

<script>
    new Vue({
           el:'.app',
           data:{
            items:[]
           },
           methods:{
               add(){
                    var div = this.$refs.box,
                        time = new Date().getTime(),
                        item = {'time':time};
                        
                    this.items.push(item);
                    div.scrollTop = div.scrollHeight;
               }
           }
       })
 </script>

效果图:

问题分析:由于vue采用虚拟dom,我每次生成新的消息时获取到的div的scrollHeight的值是生成新消息之前的值,所以造成每次都是最新的那条消息被隐藏掉了!为了论证我的分析是正确的特意做个试验,把每次vue在重新渲染dom的前后时间点和DIV的scrollHeight打印出来以做对比:

new Vue({
           el:'.app',
           data:{
            items:[]
           },
           beforeUpdate(){
            var div = this.$refs.box;
               console.log(`我被更新Dom之前,更新时间:${new Date().getTime()},更新前的div.scrollHeight是:${div.scrollHeight}`)
           },
           updated(){
            var div = this.$refs.box;
               console.log(`我被更新了Dom,更新时间:${new Date().getTime()},前后时间差:${new Date().getTime() - time} 毫秒,更新后的div.scrollHeight是:${div.scrollHeight}`)
           },
           methods:{
               add(){
                    time = new Date().getTime();
                    var div = this.$refs.box;
                    var item = {'time':time};
                    this.items.push(item);
                    console.log(`点击了添加按钮,更新时间:${time},此时的div.scrollHeight是:${div.scrollHeight}`)
                    div.scrollTop = div.scrollHeight;
               }
           }
       })

查看打印日志:

果然与我分析的一致!既然找到了原因那么就好解决问题了,我们在vue的updated状态之后去尝试获取DIV的scrollHeight就能保证是最新的内容高度了。使用异步处理setTimeout函数获取最新的div.scrollHeight,这样就能确保滚动条每次滑动至最底部!代码如下:

new Vue({
           el:'.app',
           data:{
            items:[]
           },
           beforeUpdate(){
            var div = this.$refs.box;
               console.log(`我被更新Dom之前,更新时间:${new Date().getTime()},更新前的div.scrollHeight是:${div.scrollHeight}`)
           },
           updated(){
            var div = this.$refs.box;
               console.log(`我被更新了Dom,更新时间:${new Date().getTime()},前后时间差:${new Date().getTime() - time} 毫秒,更新后的div.scrollHeight是:${div.scrollHeight}`)
           },
           methods:{
               add(){
                    time = new Date().getTime();
                    var div = this.$refs.box;
                    var item = {'time':time};
                    this.items.push(item);
                    //此时必须异步执行滚动条滑动至底部
                    setTimeout(()=>{
                        console.log(`点击了添加按钮,更新时间:${time},此时的div.scrollHeight是:${div.scrollHeight}`)
                        div.scrollTop = div.scrollHeight;
                    },0)
               }
           }
       })

现在来打开控制台看看:

好了,到这问题完美解决了!

### 使用 Vue 和 CSS 实现 Div 内容超出后自动滚动底部 为了使 `div` 的内容在超过容器高度时能够自动滚动底部,可以采用组合方式利用CSS设置基础样式并借助Vue中的生命周期钩子或者事件监听器通过JavaScript来动态调整滚动条的位置。 #### 利用 CSS 设置基本结构 首先定义好具有固定高度以及开启溢出隐藏特性的父级元素,并允许其内部可垂直方向上发生滚动行为: ```css .scrollable-div { height: 300px; /* 可自定义 */ overflow-y: auto; } ``` 此部分仅负责提供可视化的框架支持[^1]。 #### 结合 JavaScript (Vue 方法) 控制滚动位置 对于较为复杂的需求比如页面加载完成之后立即将视图定位到后一条消息处,则可以在组件挂载完成后执行一次强制刷新布局的操作,在 mounted 阶段调用 `$nextTick()` 来确保 DOM 已经更新完毕再处理后续逻辑;也可以监听新增加的内容触发相应的函数去计算新的偏移量从而达到平滑过渡的效果。 下面是一个简单的例子展示如何在一个新项目里实现这一功能: ```javascript <template> <div ref="scrollContainer" class="scrollable-div"> <!-- 动态渲染的数据列表 --> <ul> <li v-for="(item, index) in items" :key="index">{{ item }}</li> </ul> </div> </template> <script> export default { data() { return { items: ['Item 1', 'Item 2'] // 假设这是初始项集合 }; }, methods: { scrollToBottom() { this.$refs.scrollContainer.scrollTop = this.$refs.scrollContainer.scrollHeight; } }, watch: { items(newVal){ this.scrollToBottom(); } }, mounted(){ this.scrollToBottom(); } }; </script> ``` 上述代码片段展示了怎样创建一个响应式的 Vue 组件,它会在每次数据变化时尝试把焦点移动到新追加的信息那里。这里使用了 `ref` 属性获取对指定 HTML 元素的直接访问权限以便于操纵它的属性值,而 `watcher` 能够监视数组的变化情况进而及时作出反应。
评论 10
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值