简介小程序
看到今日头条小程序页面能够滑动切换,并且tab导航条也会跟着滚动,点击tab导航,页面滑动,切导航栏也会跟着滚动,就想着要怎么实现这个功能api
像商城类商品类目若是作成左右滑动切换类目用户体验应该会好不少,我这里只是一个小demo,没有怎么去考虑数据的问题,主要是想着去实现这么个功能,有可能后期引入数据后会出现问题,欢迎提出互相讨论网络
解决过程app
1.在想要实现这个问题的时候找了很多别人的博客看,主体页面布局方面是比较统一的,tab导航栏使用<scroll-view>标签,内容使用<swiper>,其中的使用方法和参数但愿自行参考api文档,不过多解释xss
布局代码以下:函数
wxml布局
<view class="container"> <!-- tab导航栏 --> <!-- scroll-left属性能够控制滚动条位置 --> <!-- scroll-with-animation滚动添加动画过渡 --> <scroll-view scroll-x="true" class="nav" scroll-left="{{navScrollLeft}}" scroll-with-animation="{{true}}"> <block wx:for="{{navData}}" wx:for-index="idx" wx:for-item="navItem" wx:key="idx"> <view class="nav-item {{currentTab == idx ?'active':''}}" data-current="{{idx}}" bindtap="switchNav">{{navItem.text}}</view> </block> </scroll-view> <!-- 页面内容 --> <swiper class="tab-box" current="{{currentTab}}" duration="300" bindchange="switchTab"> <swiper-item wx:for="{{[0,1,2,3,4,5,6,7,8]}}" wx:for-item="tabItem" wx:for-index="idx" wx:key="idx" class="tab-content"> {{tabItem}} </swiper-item> </swiper> </view>
wxss测试
/**index.wxss**/ page{ width: 100%; height: 100%; } .container{ width: 100%; height: 100%; } .nav { height: 80rpx; width: 100%; box-sizing: border-box; overflow: hidden; line-height: 80rpx; background: #f7f7f7; font-size: 16px; white-space: nowrap; position: fixed; top: 0; left: 0; z-index: 99; } .nav-item { width: 20%; display: inline-block; text-align: center; } .nav-item.active{ color: red; } .tab-box{ background: greenyellow; padding-top: 80rpx; height: 100%; box-sizing: border-box; } .tab-content{ overflow-y: scroll; }
js动画
//index.js //获取应用实例 const app = getApp() Page({ data: { motto: 'Hello World', userInfo: {}, hasUserInfo: false, canIUse: wx.canIUse('button.open-type.getUserInfo'), navData:[ { text: '首页' }, { text: '健康' }, { text: '情感' }, { text: '职场' }, { text: '育儿' }, { text: '纠纷' }, { text: '青葱' }, { text: '上课' }, { text: '下课' } ], currentTab: 0, navScrollLeft: 0 }, //事件处理函数 onLoad: function () { if (app.globalData.userInfo) { this.setData({ userInfo: app.globalData.userInfo, hasUserInfo: true }) } else if (this.data.canIUse) { // 因为 getUserInfo 是网络请求,可能会在 Page.onLoad 以后才返回 // 因此此处加入 callback 以防止这种状况 app.userInfoReadyCallback = res => { this.setData({ userInfo: res.userInfo, hasUserInfo: true }) } } else { // 在没有 open-type=getUserInfo 版本的兼容处理 wx.getUserInfo({ success: res => { app.globalData.userInfo = res.userInfo this.setData({ userInfo: res.userInfo, hasUserInfo: true }) } }) } wx.getSystemInfo({ success: (res) => { this.setData({ pixelRatio: res.pixelRatio, windowHeight: res.windowHeight, windowWidth: res.windowWidth }) }, }) }, switchNav(event){ var cur = event.currentTarget.dataset.current; //每一个tab选项宽度占1/5 var singleNavWidth = this.data.windowWidth / 5; //tab选项居中 this.setData({ navScrollLeft: (cur - 2) * singleNavWidth }) if (this.data.currentTab == cur) { return false; } else { this.setData({ currentTab: cur }) } }, switchTab(event){ var cur = event.detail.current; var singleNavWidth = this.data.windowWidth / 5; this.setData({ currentTab: cur, navScrollLeft: (cur - 2) * singleNavWidth }); } })
页面代码如上面三部分,能够直接新建一项目进行测试this
效果图以下
注意事项
在处理顶部tab导航跟随底部页面滑动的时候遇到一个问题,就是在给<scroll-view>中的scrll-left赋值的时候遇到的问题
逻辑上讲初始时tab导航下标小于2时导航栏不滚动,当大于2时向左滑动,以使被选中的导航栏居中,可是当最左侧的选项由于左滑看不到后,我又点击左侧选项但愿导航往右滑动,可以看到左边的导航,按上面的js代码计算scroll-left会产生负值,可是scroll-left即便为负值,可是滚动条不会向左缩进去,因此即便为负值,至关于为0,当时作的时候一直在思考这个怎么用逻辑解决,想着要写各类判断,计算距离,结果到最后一句代码直接赋值就搞定了,也是很无语。
小结
以上只是测试demo,可作参考,若有同窗经过这个demo引入数据而且成功的话或者失败的话,欢迎沟通探讨!!!