方案说明:
方案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 }, /** * 生命周期函数--监听页面加载 */ onl oad(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处理,滑动会有来回闪动的情况
这些只是大致思路,还有很多细节需要处理和考.......
标签:滚动,name,--,微信,scroll,高度,height,id,view From: https://www.cnblogs.com/aries-web/p/16768426.html