微信小程序实现顶部固定 底部分页滚动效果

   2023-02-09 学习力0
核心提示:目录方案说明:思路说明:常见商品页效果:顶部banner+分类,下面商品列表。方案说明:方案1:整个页面滚动,滚动至某个位置fixed图中“顶部box2”,分页页面触底加载方案2:页面高度为屏幕高度,商品部分使用scroll-view,scroll-view初始高度为屏幕高度-顶部

常见商品页效果:顶部banner+分类,下面商品列表。

微信小程序实现顶部固定 底部分页滚动效果

方案说明:

方案1:整个页面滚动,滚动至某个位置fixed图中“顶部box2”,分页页面触底加载

方案2:页面高度为屏幕高度,商品部分使用scroll-view,scroll-view初始高度为屏幕高度-顶部高度,只滚动scroll-view。

思路说明:

  1 将整个页面分为上下两部分,整个页面高度100vh(原因1:scroll-view高度需要固定高度;原因2:出现两个滚动条)

  2 页面上半部分包括banner(box1)以及固定的搜索及tab(box2)

  3 根据顶部box的高度,算出下面scroll-view的高度(windowHieght - 200)

  4 scroll-view滑动到 顶部box1+margin10的高度,将box1隐藏,box2动画移至顶部;下面scroll高度+滚动高度(或box1高度) + margin10高度(确保scroll的商品吸顶之后任然沾满屏幕)

方案3:使用插件

选择的是方案2,为什么不选择方案1,我们来剖析一下。

方案1适合页面交互比较简单,根据页面滚动高度隐藏展示即可。

  场景1:tab吸顶之后,切换tab请求数据,页面就会渲染为最初样式,不会吸顶。(请求会重新setData数据,有些数据有多有少)

复制以下代码可以直接演示demo效果

demo.wxml

<!--pages/demo/demo.wxml-->
<view class="wrap">
  <view class="top-box" style="{{boxStyle}}">
    <view class="top-box1" style="{{box1Style}}">顶部box1</view>
    <!-- <view class="top-box2"></view> -->
    <scroll-view class="top-box2" scroll-into-view="{{scrollId}}" scroll-x="true"scroll-with-animation="true" >
      <block wx:for="{{cates}}" wx:key="index">
        <view class="{{item.id === currentId?'cate-item-act cate-item':'cate-item'}}" data-id="{{item.id}}" id="good{{item.id}}" bindtap="cateChange">{{item.name}}</view>
      </block>
    </scroll-view>
  </view>
  <scroll-view scroll-y="true" class="scroll-con" style="{{scrollViewStyle}}" bindscroll="goodsViewScroll" bindscrolltoupper="goodsViewScrollTop">
    <view class="scroll-con-item" wx:for="{{cates}}" wx:key="index">{{item.name}}</view>
  </scroll-view>
</view>

demo.js

Page({
  data: {
    cates:[
      {id:null,name:'全部'},
      {id:1,name:'分类1'},
      {id:2,name:'分类2'},
      {id:3,name:'分类3'},
      {id:4,name:'分类4'},
      {id:5,name:'分类5'},
      {id:6,name:'分类6'},
      {id:7,name:'分类7'},
      {id:8,name:'分类8'}
    ],
    currentId:null,
    serviceList:[
      {id:1,name:'1'},
      {id:2,name:'2'},
      {id:3,name:'3'},
      {id:4,name:'4'},
      {id:5,name:'5'},
      {id:6,name:'6'},
      {id:7,name:'7'},
      {id:8,name:'8'}
    ],
    scrollId:null,//滑动id,切换tab效果
    animationStyle:'',
    isNeedFixed:false
  },
  /**
   * 生命周期函数--监听页面加载
   */
  onLoad(options) {
    let that = this;
    wx.getSystemInfo({
      success: function (res, rect) {
        that.setData({
          // 商品scroll高度 = 可使用窗口 - (顶部box的高度+margin20 -20(底部留白))
          scrollViewHeight: parseInt(res.windowHeight - 220 -20),
          scrollViewStyle:`height:${parseInt(res.windowHeight - 220-20)}px`
        })
      }
    })
  },
  cateChange(e){
    let currentId = e.currentTarget.dataset.id;
    let scrollId = e.currentTarget.id;
    this.setData({
      currentId,
      scrollId
    })
  },
  // 加this.data.isNeedFixed条件防止频繁的setdata
  // 1 隐藏box1,box2会自动吸顶 box2置顶
  // 2 设置scroll-view高度+120, 设置顶部box高度为box2高度
  goodsViewScroll(e){
    console.log(e.detail.scrollTop, this.data.isNeedFixed)
    if(e.detail.scrollTop >= 120 ){
      console.log('可以动画调整位置了')
      this.setData({
        isNeedFixed:true,
        box1Style:`height:0px;`,
        boxStyle:`height:80px;`,
        scrollViewStyle: `height:${this.data.scrollViewHeight + 120}px`,  
      }
    }
    // if(e.detail.scrollTop < 120 ) {
    //   console.log('需要保持原样')
    //   this.setData({
    //     isNeedFixed:false,
    //     box1Style:`height:110px;`,
    //     boxStyle:`height:200px;`,
    //     scrollViewStyle: `height:${this.data.scrollViewHeight}px`,
    //   },()=>{
    //     wx.pageScrollTo({
    //       scrollTop: 0,
    //     })
    //   })
    // }
  },

  goodsViewScrollTop(e){
       this.setData({
        isNeedFixed:false,
        box1Style:`height:110px;`,
        boxStyle:`height:200px;`,
        scrollViewStyle: `height:${this.data.scrollViewHeight}px`,
      })
  }
})

demo.wxss

.wrap {
  height: 100vh;
}
.top-box {
  height: 200px;
  height: 200px;
  background-color: #fff;
  border: 1px solid #d1d1d1;
  transition:height 0.2s;
    -webkit-transition:height 0.2s; /* Safari */
}
.top-box1 {
  height: 110px;
  width: 100%;
  margin-bottom: 10px;
  background-color: #3293FF;
  overflow: hidden;
  transition:height 0.2s;
  -webkit-transition:height 0.2s; /* Safari */
}
.top-box2 {
  height: 80px;
  width: 100%;
  background-color: #ffbe32;
  white-space: nowrap;
  padding: 50rpx 0;
  box-sizing: border-box;
}
.top-box2 .cate-item {
  display: inline-block;
  padding: 10rpx 20rpx;
  font-size: 26rpx;
  margin-right: 20rpx;
  color: #767A84;
}
.top-box2 .cate-item:last-child{
  margin-right: 0rpx;
}
.top-box2 .cate-item-act {
  background: #3293FF;
  color: #fff;
  border-radius: 48rpx;
}
.scroll-con {
  padding: 0 10px;
  margin-top: 20px;
  box-sizing: border-box;
  background-color: #fff;
}
.scroll-con-item {
  height: 100px;
  width: 100%;
  background-color: salmon;
  margin-bottom: 10px;
}
.ani-btn {
  display: inline-block;
  padding: 20rpx;
  margin: 10rpx;
  border: 1px solid #d1d1d1;
}
@keyframes move{ from{transform: translateY( 30px)} to {transform: translateY( 0px)}}

说明1:scroll-into-view 设置哪个方向可滚动,则在哪个方向滚动到该元素

  scroll-view设置x轴滚动到scrollId位置 scroll-x="true"scroll-into-view="{{scrollId}}"    

  item子元素设置id="good{{item.id}}" 由于id不能已数字开头,所以前面拼了"good"

说明2:为什么要在bindscrolltoupper触顶事件中处理初始化样式,而不是在bindscroll的时候处理?

  使用bindscroll处理,滑动会有来回闪动的情况

这些只是大致思路,还有很多细节需要处理和考.......

原文地址:https://www.cnblogs.com/aries-web/p/16768426.html
 
反对 0举报 0 评论 0
 

免责声明:本文仅代表作者个人观点,与乐学笔记(本网)无关。其原创性以及文中陈述文字和内容未经本站证实,对本文以及其中全部或者部分内容、文字的真实性、完整性、及时性本站不作任何保证或承诺,请读者仅作参考,并请自行核实相关内容。
    本网站有部分内容均转载自其它媒体,转载目的在于传递更多信息,并不代表本网赞同其观点和对其真实性负责,若因作品内容、知识产权、版权和其他问题,请及时提供相关证明等材料并与我们留言联系,本网站将在规定时间内给予删除等相关处理.

  • 小程序上传wx.uploadFile - 小程序请假-请求
    小程序上传wx.uploadFile - 小程序请假-请求
    小程序上传wx.uploadFileUploadTask wx.uploadFile(Object object)将本地资源上传到服务器。客户端发起一个 HTTPS POST 请求,其中 content-type 为 multipart/form-data。使用前请注意阅读相关说明。num=1;当num==3时,设置按钮隐藏直接上代码:view class='
    03-08
  • 微信小程序中overflow:scroll失效的问题 微信小程序overflow设置滚动
    微信小程序中overflow:scroll失效的问题 微信小
    .common-pop-table {padding: 0 30rpx;overflow: scroll;max-height: 70%;}研究后发现,要实际的设置对应的那个维度的高度,wcss改成.common-pop-table {padding: 0 30rpx;overflow: scroll;max-height: 400px;}就恢复正常了
    03-08
  • 小程序 AI/AR 能力
    一、关于 VisionKit1、定义VisionKit 为小程序提供了开发 AR 功能的能力,包含了 AR 在内的视觉算法。2、版本提供了 V1 和 V2 两个版本,区别如下:V1平面接口,适用于用户在平面场景下,例如桌面,地面,泛平面场景,放置虚拟物体,不提供真实世界距离。用户
    03-08
  • Python小程序——快排算法 快排 python
    1 def Partition(list,p,q): 2 #这里是用来分块的算法。 3 x = list[p] 4 i = p 5 for j in range(p+1,q+1): #注意range是顾前不顾后的,所以后面的区间值要大一位 6 if list[j]x: 7 i+=1 8 list[i],list[j] = list[j],list[i] 9 10 list[p], list[i] = list[
    02-09
  • 总结一些 egret项目接小程序时 遇到的问题及解决方法
    总结一些 egret项目接小程序时 遇到的问题及解
    1,https://blog.csdn.net/u013052238/article/details/81456908  这个地址的一些问题 是一部分,其中 第6条,当在wxgame.ts中仿照已有的 暴露库给window的方法写完之后,仍会报错,本人遇到的是 : jszip is not defined :  也尝试过其他前辈分享的解决方
    02-09
  • c++第一个小程序 第一个小程序是什么
     #include iostreamusing namespace std;int main(){const int SIZE=50;//定义大小。char name[SIZE]; cout"please input you name!\n"; //提示cinname;//输入cout"hello world:"nameendl; //输出return 0;}   #include iostreamusing namespace std;int m
    02-09
  • 微信小程序 错误记录
    1、报错this.getUserInfo(this.setData) is not a function;at pages/index/index onShow function;at api request success callback functionTypeError: this.getUserInfo is not a function在回调结果里调用这个页面的函数 this.fun() 或者 this.setData 时
    02-09
  • 【小程序】添加tabBar后navigateTo失效
    某页面.js//事件处理函数bindViewTap() {wx.navigateTo({url: '../logs/logs',})}, app.json"tabBar": {"backgroundColor": "black","color":"white","list": [{"pagePath": "pages/index/inde
    02-09
  • 微信小程序npm引入vant-weapp库的方法
    微信小程序npm引入vant-weapp库的方法
    1、终端打开小程序所在目录  2、npm init初始化,初始化完成之后,小程序项目中就会出现package.json文件,说明已经初始化成功 3、npm install --production 安装生产环境,不要npm install都给装上,以免小程序包过大  4、安装vant :npm i vant-weapp
    02-09
  • 小程序组件之间的通信 小程序子父子组件通信
    前言:其实之前就想写这个的,因为我觉得这么模块化的框架,组件之间通信是非常重要的,也是最经常用到的一块儿,只是之前在项目里一直没用到跨组件通信,现在用到了,也会用了,就一起写出来得了 :) 一、父、子组件之间的通信注:首先我们先将子组件在父组
    02-09
点击排行