uniapp滚动监听元素

匿名 (未验证) 提交于 2019-12-03 00:15:02

鸽了这么久,一晃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]&&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>

二、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地址:

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!