zoukankan      html  css  js  c++  java
  • uniapp滚动监听元素

    鸽了这么久,一晃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地址: https://github.com/steffenx/timeLine-uniapp.git

  • 相关阅读:
    ntohs, ntohl, htons,htonl的比较和详解【转】
    Device Tree 详解【转】
    浅析Linux DeviceTree【转】
    【spring boot】spring boot 拦截器
    【jQuery】jQuery/js 判断字符串是否JSON字符串
    【java】java中的 &= 和 |= 和 ^= 的区别
    zabbix创建触发器、action,发送报警邮件
    html iframe禁用右键
    mysql数据库mysqldump方式备份
    JDK8新特性
  • 原文地址:https://www.cnblogs.com/Steffen-xuan/p/11761561.html
Copyright © 2011-2022 走看看