uni-app 之 聊天室頁面滾動到底部


uni-app 之 聊天室滾到最底部

  請注意 !:  知識點為uni-app 與 vue 結合

  這次寫到聊天室,碰到一個emmmmm問題比較嚴重的事情,聊天嘛,咱們想實現的就無非是微信,QQ那種聊天的效果嘛,我們研究了,,,,emmmm  (n久之長),終於是把這個功能寫出來了,代碼等什么時候整理出來給大家看,今天主要說一下碰到的一個問題,就是我發送消息的時候, 想要將消息彈出,發一條彈一條,代碼附上

  注意:scroll-view要設置高度

  輸入內容后,必然要在對話界面的底部顯示內容,可以通過uni.pageScrollTo的方式,但是這個頁面刷新的太厲害,輸入框都刷新了,沒法使用。所以只能使用scroll-view組件。但是通過scroll-view使用豎向滾動時,需要給 一個固定高度。為了適配屏幕的大小,則需要通過計算來確定scroll-view的高度。

<view class="content" id="content" :style="{height: style.contentViewHeight + 'px'}">
            <scroll-view id="scrollview" class="chat-window" scroll-y="true" :style="{height: style.contentViewHeight + 'px'}" :scroll-with-animation="true" :scroll-top="scrollTop">
                <!-- <view class="chat-window"> -->
                    <view class="small-talk_time">12:18</view>
                    <!-- 聊天內容 -->
                    <view class="content-all">
                        <!-- 聊天窗口 -->
                        <view :class="item.type" v-for="(item, index) in chatRecord" :key="index" class="m-item">
                            <!-- 收信人 -->
                            <view class="talk-text talk-left" v-if="item.type == 'talk-left'">
                                <!-- 收信人頭像 -->
                                <view class="talk-photo">
                                    <image src="../../static/images/myself.jpg" class="talk-img"></image>
                                </view>
                                <!-- 收信人消息 -->
                                <view class="talk-content">
                                    <view class="talk-huge"></view>
                                    <view class="talk-title">{{item.message}}</view>
                                </view>
                            </view>
                            <view class="talk-text talk-right" v-if="item.type == 'talk-right'">
                                <!-- 發信人消息 -->
                                <view class="talk-content">
                                    <view class="talk-title">{{item.message}}</view>
                                    <view class="talk-huge"></view>
                                </view>
                                <!-- 發信人頭像 -->
                                <view class="talk-photo">
                                    <image src="../../static/images/myself.jpg" class="talk-img"></image>
                                </view>
                            </view>
                        </view>
                    </view>
                <!-- </view> -->
            </scroll-view>
        </view>

 既然是聊天 先將聊天頁面寫出來 寫好了你說我說的樣式  大概就是這個樣子

接下來是咱們的js了

 
         

 created () {
   const res = uni.getSystemInfoSync();   //獲取手機可使用窗口高度     api為獲取系統信息同步接口
   this.style.pageHeight = res.windowHeight;
   this.style.contentViewHeight = res.windowHeight - uni.getSystemInfoSync().screenWidth / 750 * (100) - 70; //像素   因為給出的是像素高度 然后我們用的是upx  所以換算一下 
   this.scrollToBottom();   //創建后調用回到底部方法
 },     

export default {
  data (){
     //
聊天頁面時時滾動樣式 style: { pageHeight: 0, contentViewHeight: 0, footViewHeight: 90, mitemHeight: 0 },
  }
}

js代碼:

   /**
         * @author gongliying
         * @date 2019-07-26
         * @information 跳轉頁面底部
         */
        scrollToBottom: function () {
            let that = this;
            let query = uni.createSelectorQuery();
            query.selectAll('.m-item').boundingClientRect();
            query.select('#scrollview').boundingClientRect();
            query.exec((res) => {
                that.style.mitemHeight = 0;
                res[0].forEach((rect) => that.style.mitemHeight = that.style.mitemHeight + rect.height + 40)   //獲取所有內部子元素的高度 if (that.style.mitemHeight > (that.style.contentViewHeight - 100)) {   //判斷子元素高度是否大於顯示高度
                    that.scrollTop = that.style.mitemHeight - that.style.contentViewHeight    //用子元素的高度減去顯示的高度就獲益獲得序言滾動的高度
                }
       })
        }

  這一步做的主要就是獲取這個‘.m-item’這個里面的節點信息   uni-app雖然不支持window和document 但是咱們還是有一個api可以獲取他元素的信息的 就算是uni.createSelectorQuery()這個api,他會返回一個 SelectorQuery 對象實例。可以在這個實例上使用 select 等方法選擇節點,並使用 boundingClientRect 等方法選擇需要查詢的信息。這個exec()他會執行這里面所有的請求,我們最后會獲取到他的id dataset 左邊界坐標  右邊界坐標 上邊界坐標 下邊界左邊 節點的寬度  節點的高度   具體的這個方法的使用可以去官網查看一番,我就不具體解釋了  畢竟今天重點不是他呀    回到 原題   咱們說了   在最開始created的時候獲取你當前使用手機的品牌啊  型號啊   我們這里主要的是獲取可使用窗口的高度     然后我們又獲取了所有子元素的告訴   然后就可以看着我的注釋走了~~~~

  但是呢。你們不要以為這樣就好了  , 還有一個很重要的事情,如果你們認真看了這段代碼還有就是實驗了一下, 你們會發現到最后那個滾動條沒有滾動到最底部,會發現最后一調消息被隱藏了,也不是沒有 ,頁面上有這條消息,但是呢就是沒有彈出來,后來呢,

仔細分析了一下,因為由於vue采用虛擬dom,我每次生成新的消息時獲取到的div的scrollHeight的值是生成新消息之前的值,所以造成每次都是最新的那條消息被隱藏掉了!這就是開頭我跟大家說注意這是uni-app和vue結合的原因了

  解決方法:采用異步處理settimeout函數獲取最新的scrollheight  讓他先全部執行完了之后去走這個異步,這樣就能確保滾動條每次滾到的都是最底部  上段代碼更改如下:

  

/**
         * @author gongliying
         * @date 2019-07-26
         * @information 跳轉頁面底部
         */
        scrollToBottom: function () {
            let that = this;
            let query = uni.createSelectorQuery();
            query.selectAll('.m-item').boundingClientRect();
            query.select('#scrollview').boundingClientRect();
            query.exec((res) => {
                that.style.mitemHeight = 0;
                res[0].forEach((rect) => that.style.mitemHeight = that.style.mitemHeight + rect.height + 40)   //獲取所有內部子元素的高度

           // 因為vue的虛擬DOM 每次生成的新消息都是之前的,所以采用異步setTimeout    主要就是添加了這紅字
           setTimeout(() => {

                  if (that.style.mitemHeight > (that.style.contentViewHeight - 100)) {   //判斷子元素高度是否大於顯示高度
                      that.scrollTop = that.style.mitemHeight - that.style.contentViewHeight    //用子元素的高度減去顯示的高度就獲益獲得序言滾動的高度
   }
         }, 100)        }) }

最后實現了每次聊天都是滾到最底部  要是想要進入頁面就滾到最底部呢  我們是在socket鏈接讀取文件的時候調用了這個方法

ending~~~~

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM