小程序-导航栏悬浮+切换导航栏滚动页面+滚动页面切换导航栏

前言


 很多小程序、app都有这种设计:

效果1.将导航栏固定在页面顶部。

效果2.点击导航栏,页面自动滚动到对应内容位置。

效果3.滚动页面自动切换至对应导航栏

效果演示:

代码

wxml

<!-- 导航栏 -->
<view class="topView">
<scroll-view class="tabs" scroll-x="true" scroll-with-animation=‘true‘ scroll-into-view="x{{xId}}">
<view class="tab {{xId==item.id?‘greenColor‘:‘‘}}" wx:for="{{list}}" wx:key="item"
catchtap="changeTab" id="x{{item.id}}">
<view class="tab_text">{{item.title}}</view>
<view class="tab_line {{xId==item.id?‘greenBg‘:‘‘}}"></view>
</view>
</scroll-view>
</view>

<view style="height:80rpx"></view>

<!-- 滚动内容 --> <scroll-view class="columns" scroll-y="true" scroll-with-animation=‘true‘ scroll-into-view="f{{yId}}" style=‘height:{{height}}rpx;‘ bindscroll="scrollFloor"> <view class="column " wx:for="{{list}}" wx:key="item" id="f{{item.id}}"> <view class="column_title">{{item.title}}</view> <view class="column_imgs"> <view class="img_div" wx:for="{{item.photo}}" wx:for-item="items" wx:key="items"> <image src="{{items}}" mode="aspectFill"></image> </view> <view class="img_div" wx:if="{{item.photo.length>7}}"> <view class="showMore">点击查看更多</view> </view> </view> </view> <view style="height:200rpx"></view> </scroll-view>

属性解释:

scroll-x="true": 允许横向滚动,反之 scroll-y="true" 允许纵向滚动。

scroll-with-animation:在设置滚动条位置时是否使用动画过渡。

scroll-into-view:滚动到哪个元素(值应为某子元素id【id不能以数字开头】,例如本文的:id="x{{item.id}}" 或 id="f{{item.id}}" 设置哪个方向可滚动,则在哪个方向滚动到该元素)。

bindscroll:内容滚动时触发的事件。

wxss

.greenColor {
color: rgb(59 185 80);
}
.greenBg {
background-color: rgb(59 185 80);
}
.topView {
position: fixed;
top:0rpx;
left:0rpx;
z-index:999;
width:100%;
background-color: #fff;
height: 80rpx;
}
/* 导航tab */
.tabs {
white-space: nowrap;
padding-left: 32rpx;
width: 100%;
overflow: hidden;
}
/* 隐藏scroll-view页面滚动条 */
::webkit-scrollbar {
width: 0;
height: 0;
color: #fff;
display: none;
}
.tabs .tab {
display: inline-block;
padding-right: 50rpx;
}
.tab_text {
height: 50rpx;
line-height: 50rpx;
padding-bottom: 10rpx;
}
.tab_line {
margin: 0 auto;
width: 30rpx;
height: 5rpx;
}
/*滚动内容*/ .column { width: 100%; box-sizing: border-box; overflow: hidden; } .column .column_title { padding: 40rpx 32rpx 0rpx 32rpx; } .column .column_imgs { padding: 0 28rpx; overflow: hidden; margin-top: 15rpx; } .column_imgs .img_div { width: 230rpx; height: 190rpx; padding: 7rpx 7rpx; box-sizing: border-box; float: left; display: -webkit-flex; -webkit-flex-wrap: nowrap; flex-wrap: nowrap; } .column_imgs .img_div image { width: 100%; height: 100%; background: #b5b5b5; } .column_imgs .img_div .showMore { width: 100%; height: 100%; background: #f3f5f8; line-height: 190rpx; text-align: center; font-size: 28rpx; color: #0f0d6b; }

js

Page({
data: {
height: 0,         //页面高度 rpx
ratio: 0,          //rpx,px转化比
xId: 1,           //x轴选中项
yId: 1,           //y轴滚动位置
    heightArray: [],
list: [{
id: 1,
title: "特色",
photo: [
"图片url",
"图片url",
"图片url"        ],
},
{
id: 2,
title: "楼盘",
photo: [
"图片url",
"图片url"
],
},
{
id: 3,
title: "样板房",
photo: [
"图片url",
"图片url"
],
},
{
id: 4,
title: "周边配套",
photo: [
"图片url",
""
],
},
{
id: 5,
title: "售楼处",
photo: [
"图片url",
"图片url"
],
},
{
id: 6,
title: "楼盘证件",
photo: [
"t图片url",
"图片url"
],
},
]
},
onLoad: function (options) {
let that = this
wx.setNavigationBarTitle({
title: ‘相册页‘
})
//1. 获取页面高度
    wx.getSystemInfo({
success: function (res) {
let width = res.windowWidth
let ratio = 750 / width
let height = ratio * res.windowHeight
that.setData({
height: height, //单位rpx
          ratio: ratio
})
}
})
  },
onShow: function () {
let that = this,
heightArray = [];
//1.获取滚动元素距离顶部位置-y
setTimeout(function () {
let query = wx.createSelectorQuery() //创建节点查询器
query.selectAll(‘.column‘).boundingClientRect(function (rect) {
rect.forEach(function (value) {
heightArray.push((value.top - (170 / that.data.ratio)))
})
that.setData({
heightArray
})
}).exec()
}, 1000) //此处最好用延时,否则获取的结果有可能是null,也有可能值不准确。 
  },
//切换tab导航栏
changeTab: function (e) {
let that = this
let id = e.currentTarget.dataset.id
that.setData({
xId:id,
yId:id,
})
},
//监听滚动 切换tab
scrollFloor: function (e) {
var that = this
var scrollTop = e.detail.scrollTop //滚动条距离顶部
var heightArray = that.data.heightArray //滚动项距离顶部
var id = null
//计算比较得出下标
for (let i = 0; i <= heightArray.length; i++) {
if (scrollTop >= heightArray[i] - 90 && scrollTop < heightArray[i + 1]) {
id = that.data.list[i].id
}
}
that.setData({
xId: id
})
},
})

思路

效果1 导航栏悬浮:

父盒子class="topView" 包裹scroll-view 导航栏,父盒子样式属性

.topView {
  position: fixed;
  top:0rpx;
  left:0rpx;
  z-index:999;
  width:100%;
  background-color: #fff;
  height: 80rpx;
}

注意:

1.z-index提高层级,避免被滚动内容覆盖。

2.宽度一定要设置,不然会顶部tab栏将无法左右滑动。

3.scroll-view 组件使用:white-space: nowrap;overflow: hidden; 并且其子元素设置 :display: inline-block;

效果2  点击导航栏,页面自动滚动到对应内容位置:

 导航栏绑定点击事件changeTab,并通过data-id把当前tab的元素的id值传给事件,改变xId(导航栏选中项)和yId(滚动内容选中项)的值。

效果3 滚动页面自动切换至对应导航栏:

1.页面onLoad时获取页面高度并赋值给 scroll-view 的 style:height样式属性。

2.onShow时获取scroll-view 内子元素距离顶部距离并依次保存在heightArray数组中。

3.页面滚动触发scrollFloor事件,获取scroll-view 整个滚动框距离顶部的距离scrollTop,遍历heightArray,如果scrollTop介于heightArray[i]和heightArray[i+1]之间,则说明页面已经滚动至i元素,把i元素的id赋值给xId。

小结

以上便是我对这个功能的理解跟实现方法,代码均已给出,各位同学有疑问或者有其他解决方案,欢迎沟通探讨!!!

小程序-导航栏悬浮+切换导航栏滚动页面+滚动页面切换导航栏

原文:https://www.cnblogs.com/dreamzhh/p/14949687.html

以上是小程序-导航栏悬浮+切换导航栏滚动页面+滚动页面切换导航栏的全部内容。
THE END
分享
二维码
< <上一篇
下一篇>>