【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。

相關文章
相關標籤/搜索