鴿了這么久,一晃2個月過去了。自考+上班沒時間記錄。
前不久看到移動官網上的時間軸效果,看起來不錯,我也來試着做一下。
需要元素滾動到視野內加載動畫。
插件地址 https://ext.dcloud.net.cn/plugin?id=906
uniapp不能操作dom,寫這個還是思考了很久。效果如下

一、布局
畫主軸。內容分割成塊,當出現在視野中(滾動監聽),加載載入動畫。
內容塊中分別有一個圓點、詳情內容。
<!-- 時間軸 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]&¤t[index].is=='ok'?1:0,top:'50px'}" :class="current[index]&¤t[index].is=='ok'?comeani:''"></view> <!-- 內容 --> <view class="info-content-wrap" :style="{ opacity: current[index]&¤t[index].is=='ok'?1:0}" :class="current[index]&¤t[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>
二、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(); }); },
獲取到距離頂部的距離就可以判斷是否出現在視野內,並把標志位設置為相應狀態
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
