uniapp滾動監聽元素

鴿了這麼久,一晃2個月過去了。自考+上班沒時間記錄。css

前不久看到移動官網上的時間軸效果,看起來不錯,我也來試着作一下。git

須要元素滾動到視野內加載動畫。github

插件地址 https://ext.dcloud.net.cn/plugin?id=906數組

uniapp不能操做dom,寫這個仍是思考了好久。效果以下app

 

 1、佈局

畫主軸。內容分割成塊,當出如今視野中(滾動監聽),加載載入動畫。dom

內容塊中分別有一個圓點、詳情內容。async

<!-- 時間軸 css就不貼出來了-->
            <view class="time-line-container" :class="addTypeClass">
                <!-- 時間軸內容塊列表 -->
                <view class="time-line-list">
                    
                    <!-- 時間軸內容塊   綁定id值-->
                    <view class="time-line-info" :key="index" :class="[layoutClass(index)]" :id="'timeline'+index" v-for="(item,index) of time_line_list">
                        
                        
                        <!-- 內容塊內容 -->
                        <view class="line-info-content" >
                            
                            <!-- 時間軸圓點 -->
                            <view class="line-on-round" :style="{ opacity: current[index]&&current[index].is=='ok'?1:0,top:'50px'}" :class="current[index]&&current[index].is=='ok'?comeani:''"></view>
                            <!-- 內容 -->
                            <view class="info-content-wrap" :style="{ opacity: current[index]&&current[index].is=='ok'?1:0}" :class="current[index]&&current[index].is=='ok'?comeani:''">
                                <!-- 標題 -->
                                <view class="info-title">
                                    {{item.title}}<span>{{item.title_span}}</span>
                                </view>
                                
                                <!-- 內容 -->
                                <view class="info-content">
                                    <!-- 內容 -->
                                    <view class="info-txt">{{item.content}}</view>
                                </view>
                            </view>
                            
                        </view>
                    </view>
                </view>
            </view>

2、js

首次進入頁面,需獲取屏幕高度,初始化一個current,開始獲取每一個元素的位置信息。佈局

          init(){
                try {
                    // 獲取屏幕高度
                    const res = uni.getSystemInfoSync();
                    this.HEIGHT=res.screenHeight;
                    // 添加標誌位
                    for(let i=0;i<this.time_line_list.length;i++){
                        this.current.push({tag:'timeline'+i,is:'no'});
                    }    
                    // 開始獲取位置信息
                    this.getScroll();        
                } catch (e) {
                    // error
                }
            },

循環一下全部的元素並獲取每一個元素的位置信息,獲得後加入數組動畫

        async getScroll(){
                if(!this.isScroll){return;}
                let info=[];
                // 返回位置信息加入數組 等待獲取完成再進行loadani操做
                for(let i=0;i<this.time_line_list.length;i++){
                    await this.getNodeList('timeline'+i,i).then(res => {
                        info.push(res);
                    });
                }
                this.result.push({info:info});
                // 加載動畫
                this.loadani();
            },
       getNodeList(id,i){
                // 獲取位置信息並返回
                return new Promise(resolve=>{
                    const query = uni.createSelectorQuery().in(this);
                    query.select('#'+id).boundingClientRect(data => {
                      // console.log("獲得佈局位置信息" + JSON.stringify(data));
                      // console.log("節點離頁面頂部的距離爲" + data.top);
                      resolve({domInfo:data.height,domTop:data.top,tag:id})
                    }).exec();
                });
            },

 獲取到距離頂部的距離就能夠判斷是否出如今視野內,並把標誌位設置爲相應狀態this

       loadani(){
                for(let i=0;i<this.result.length;i++){
                    for(let j=0;j<this.result[i].info.length;j++){
                        // 是否沒加載動畫
                        if(this.current[j].is!='ok'){
                            // 是否進入視野
                            if(this.current[j].tag==this.result[i].info[j].tag &&
                               this.result[i].info[j].domTop+90<this.HEIGHT){
                                // 加載動畫
                                this.current[j].is='ok';
                                this.sum=j+1;
                            }
                        }
                    }
                    // 移除當前
                    this.result.splice(i,1);
                }
                // 是否所有加載完成
                if(this.sum==this.time_line_list.length){this.isScroll=false;}
            },

在主界面,還要監聽每次的滾動,看元素是否滾動到視野內了

組件引入:

<time-line ref="timeline" location="center" title="個人時間軸"></time-line>

     onPageScroll() {
            this.$refs.timeline.getScroll();
        },

這樣就完成了,寫的有點繁瑣哈哈。省略部份內容,能夠看完整示例。

附上GitHub地址: https://github.com/steffenx/timeLine-uniapp.git

相關文章
相關標籤/搜索