在Vue中实现窗口动态调整大小并可以将滚动条保持在尾部的方案

既然要动态,肯定要动态绑定属性,纯CSS是做不到的

<div id="chat" class="container" :style="styleObject”>
</div>

设置style属性的初始值,将height不设置为具体值,是因为那样会感觉到明显的高度变化,还不如从0开始变。

data() {
    return {
        'styleObject' : {
            'width': '100%',
            'height': '0px',
            'overflow-y': 'scroll'
        }
    }
},

动态调整大小,需要关注window的两个事件,一个是加载load,一个是调整大小resize,参考另一篇文章,还做了销毁动作,节省内存,顺手而为:

created() {
    window.addEventListener("resize", this.windowResized);
    window.addEventListener("load", this.windowLoaded);
},

destroyed() {
    window.removeEventListener("resize", this.windowResized);
    window.removeEventListener("load", this.windowLoaded);
},

在method中实现具体调整大小的逻辑,至于需要从window.innerHeight去掉多少,要看自己的页面布局而定,像我这个例子,就有一个置顶的navbar,和一个置底的表单。

windowResized: function() {
    this.updateSizes();
},

windowLoaded: function() {
    this.updateSizes();
},

updateSizes: function() {
    let navbarHeight = $('#navbar-top').outerHeight();
    let messagePanelHeight = $('#message-panel').outerHeight();
    this.styleObject.height = (window.innerHeight - navbarHeight - messagePanelHeight) + 'px';
},

下一个就是加载数据,动态修改滚动条,我们遵循Vue的基本逻辑,都是修改data数据实现绑定,那么只要关注data数据的改变就好,这里就像注释描述的,一定要setTimeout,后面的延时其实是0,但也可以取到最新值,否则只能更新到最后一行前面一行。在中文的互联网上找到很多文章,直接将scrollHeight赋值给scrollTop,看起来能够实现同样的效果,但其实是不准确的。

watch: {
    messages : function(val) {
        // 滚动是有一个过程的,如果不加这么一个延时,scrollHeight取到的就是最终值
        setTimeout(function() {
            let container = document.getElementById('chat');
            container.scrollTop = container.scrollHeight - container.clientHeight;
        }, 0);
    }
},