【JavaScript系列】vue项目中实现滚动条(具体视窗口的滚动条)操做:(1)置底,(2)置于上次停留的位置

1、前言

以前写了一个happyChat的项目,主要是想学习一下socketIO的使用。而后最近在给happyChat作前端优化和升级。发现初版作的很low。html

须要优化的问题:前端

一、问题1:滚动条会出如今头部和底部的视窗中,以前固定头部和固定底部是使用`position:fixed`。

解决方案:body和html禁止`overflow:hidden`,头部和底部是`position:relative`,聊天视窗使用`overflow: auto`,这样聊天视窗才会出现滚动条。滚动条不会出如今头部和底部视窗中。

二、问题2:聊天视窗一次性加载了全部的聊天内容,若是数据太多会出现超时的问题。

解决方案:聊天内容查询使用分页查询,一次性查询20条或者30条。

三、问题3:群聊的时候,找不到群成员列表。

解决方案:作一个群信息汇总的组件,包括群成员列表。

复制代码
新增功能:(1)滚动条置底;(2)分页加载的时候,保持滚动条置于上次停留的位置。
复制代码

项目【前端】源代码地址:github.com/saucxs/happ…vue

项目【后端】端源代码地址:github.com/saucxs/happ…node

欢迎fork和start。git

线上地址:chat.chengxinsong.cn/github

2、具体【视窗口】的滚动条的问题

环境:vueweb

咱们先来看一下,给滚动条添加监听事件,必须在created或者mouted周期中,添加scroll的监听事件。后端

mounted: function () {
    window.addEventListener('scroll', this.handleScroll, true);  // 监听(绑定)滚轮滚动事件
  },
复制代码

其中handleScroll事件是methods里的事件:bash

handleScroll() {
      this.viewBox = this.$refs.viewBox;
      console.log(this.viewBox.scrollTop, '到头部的距离-------------------')
      console.log(this.viewBox.scrollHeight, '滚动条的总高度-------------------')
    }
复制代码

image
注意:div 到头部的距离 + 屏幕高度 = 可滚动的总高度 this.$refs.viewBox取到视窗口的dom对象,必须肯定dom加载完毕了。

<ul ref="viewBox">
        <li v-for="item in message">
          <ChatItem v-if="userInfo.user_id === item.from_user" :href="item.from_user" :img="item.avator" me="true" :msg="item.message" :name="item.name" :time="item.time"></ChatItem>
          <ChatItem v-else :img="item.avator" :msg="item.message" :href="item.from_user" :name="item.name" :time="item.time"></ChatItem>
        </li>
      </ul>
复制代码

若是咱们想置底,咱们必须将【滚动条总高度】赋值给【滚动条到头部的距离】。这样就置底了。app

业务是这样的:(1)当进入到聊天页面时候,这时候置底。(2)若是翻看以前的聊天记录,这时候就不须要置底,保持在当前的位置。

一、先解决【进入到聊天页面时候,这时候置底】的问题

解决方案:(1)全局设置一个标志位,若是是第一次进入,【标志位为置底】,执行置底方法。(2)若是是翻看以前聊天记录,【标志位改成不置底】,不执行置底方法。(3)监听内容变化方法,判断标志位是啥,而后看是否执行置底方法。

watch: {
    message() {
      this.viewBox = this.$refs.viewBox
      if(this.type == 'bottom'){
        this.refresh();
      }
    }
},
复制代码

refresh就是一个置底方法。

refresh() {
      setTimeout(() => {
            this.viewBox.scrollTop = this.viewBox.scrollHeight
	}, 100)
},
复制代码

二、若是翻看以前的聊天记录,这时候就【不须要置底,保持在当前的位置】

若是不置底,就是一直在保持在顶部。

思路:将加载以前的【数据高度】(此时滚动条的总高度)存放在临时变量beforeScrollHeight中;将数据加载以后的到【头部的距离】 = 【此时滚动条总高度】- 【临时变量beforeScrollHeight】。

image

看一下代码实现:

监听message值变化

watch: {
   message() {
      if(this.type == 'bottom'){
        this.refresh();
      }else{
        this.nofresh()
      }
  }
},
复制代码

主要看nofresh方法

nofresh() {
      setTimeout(() => {
        this.afterScrollHeight = this.viewBox.scrollHeight - this.beforeScrollHeight;
        this.viewBox.scrollTop = this.afterScrollHeight;
      }, 100)
},
复制代码

加载更多的方法

loadMore() {
     this.beforeScrollHeight = this.viewBox.scrollHeight;
     // 分页请求数据,包装数据。
 }
复制代码

咱们来看一下动态图,实现的功能

iamge

今天只把这个具体视窗口的滚动条的总结一下,其余两个问题,没有很大的意义。

【上述源码地址】项目地址:github.com/saucxs/happ… ,欢迎fork和start。

相关文章
相关标签/搜索