小程序滚动监听,并动画控制某元素的显示隐藏

场景:

当页面滚动高度超过元素1高度时,元素2(动画的)显示或隐藏。
在小程序中如何做到滚动监听并动态获取元素高度呢?
在开发者工具中预览效果

f0g2j-tutqz.gif
解决思路:

1.在页面渲染完成后(onReady函数里) 去获取元素1在页面上距离顶部的高度fixedTop;
2.用监听页面滚动函数 onPageScroll得到当前页面滚动高度,注意,这里得到的高度是“页面在垂直防线已滚动的距离(单位px)” ;

  1. 如上动图可知,元素1距离页面顶部的高度 = 页面已滚动的距离 + 一个平面的高度
  2. wx.getSystemInfo获得设备信息,其中设备的屏幕高度字段为res.screenHeight
具体解决过程:

我们先来看看不考虑现实隐藏的效果的实现过程
.js文件

  /**
   * 监听用户滑动页面事件--返回页面在垂直方向已滚动的距离(单位px)
   */
  onPageScroll(e){
    let isfixed = 0
    if(parseInt(e.scrollTop) + parseInt(this.data.screenHeight) > this.data.fixedTop) isfixed = 1
      else isfixed = 0;

    this.setData({isfixed });
    
  },


  /**
   * 生命周期函数--监听页面初次渲染完成
   */
  onReady: function () {

    let query = wx.createSelectorQuery();
    query.select('#notic').boundingClientRect(res => { //获取元素1距离页面顶部高度
      this.setData({
        fixedTop: res.top
      })
    }).exec()

    wx.getSystemInfo({ //获取屏幕高度
      success: (res => {
        this.setData({
          screenHeight: res.screenHeight
        })
      })
    })

  },

.wxml 文件

<view wx:if="{{isfixed}}" class="btn">附近更多活动(我是元素2)</view>

动态的控制isfixed,就可以控制到元素2的显示隐藏啦。
注意一点, wx.createSelectorQuery()获取元素的top值是指元素的margin之外的开始计算的。这里我给 元素2 设置了50的margin,为了计算的精确性,我们应该高度判断的语句减去 元素2 的margin值,例如 if(parseInt(e.scrollTop) + parseInt(this.data.screenHeight) - 100 > this.data.fixedTop) isfixed = 1




下面来看看是怎么加显示隐藏的动画的。
实现方法:用小程序的动画api实现 或 css过度实现
下来来看具体实现过程:

方法1. 小程序wx.createAnimation api实现。
createAnimation具体的用法可看官方文档,这里只说动图的实现效果,实现代码如下:

animation.png

<view wx:if="{{isfixed}}" animation="{{animate}}" class="btn">附近更多活动(我是元素2)</view>

上图(animation.png)可以看到,先是创建一个动画函数opacityAnimate,然后在onPageScroll函数中当满足条件时调用该0动画函数,我们给动画传一个为1的值,而css的opacity: 1时即透明度为0,即元素显示。而条件不满足时传0,元素透明,即不显示。
在wxml文件中,动画用animation属性来绑定,如上的wxml代码。
这里我同时用了wx:if 和 animation ,从前面我们知道wx:if就可以控制元素的显示隐藏,只是想要看到过度效果,所以后面加了animation动画。那么这里可不可只写animation来控制显隐呢,答案是可以的,但是animation我们控制的是元素的透明度,元素隐藏只是透明度为0,元素实际上是还在的。这种情况下,如果元素中绑定了事件,点击到透明的元素,一样会触发到绑定事件,所以以防万一还是用wx:if和animation同时控制妥当些。

方法2. 用css过度实现
在控制元素的opacity属性时,可以给元素加一个transition过度属性,看起来就有个动画效果不会那么生硬了。
具体实现如下:

transition.png

<view 
    wx:if="{{isfixed}}" 
    class="btn" 
    style="transition: all 0.3s;opacity: {{isfixedShow ? 1 : 0}};"
>附近更多活动(我是元素2)</view>

用transition来过度一个元素的opacity时要注意一点,,这个元素必须是先存在的,然后再去控制opacity。如上例子,
wxml文件中,元素同时用来isfixedisfixedShow两个字段来控制。
js文件中(红框部分)isfixedShow是根据isfixed变化后的100ms后才变换的,为什么要延迟呢?其实延迟多长时间可以自己酌情控制,这里想说的是“一个元素的opacity的属性想用transition来过度时,这个元素必须是先存在的”,即先有这个元素(isfixed为true) ,然后再去控制元素的透明度opacity的值。

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

推荐阅读更多精彩内容

  • 1、通过CocoaPods安装项目名称项目信息 AFNetworking网络请求组件 FMDB本地数据库组件 SD...
    阳明AI阅读 16,026评论 3 119
  • 这几天外甥女们过来玩了,早上去工作的时候,小外甥女帮我开了门,然后对我说:你要早点回来陪我玩呀。当时并没有回答...
    鸟琴y阅读 606评论 0 0
  • 比情商更重要的是逆商 如果说情商是和他人相处的能力,那么逆商,就是和自己相处的能力
    湛敏阅读 241评论 2 1
  • 一天吃一个鸡蛋的后果是怎样,你知道吗?一天一个鸡蛋,不仅能提高记忆力,还能保护视力,帮助减肥。但有些人对鸡蛋心有疑...
    沃麦加阅读 4,105评论 3 2
  • 这段时期 最多的还是画自己 随便画画 画的二黑 结。
    一白的画洞阅读 261评论 1 2