微信小程序tab切换,可滑动切换,导航栏跟随滚动实现

引用:https://www.cnblogs.com/till-the-end/p/8935152.html

简介

看到今日头条小程序页面可以滑动切换,而且tab导航条也会跟着滚动,点击tab导航,页面滑动,切导航栏也会跟着滚动,就想着要怎么实现这个功能

像商城类商品类目如果做成左右滑动切换类目用户体验应该会好很多,我这里只是一个小demo,没有怎么去考虑数据的问题,主要是想着去实现这么个功能,有可能后期引入数据后会出现问题,欢迎提出互相讨论

解决过程

1.在想要实现这个问题的时候找了不少别人的博客看,主体页面布局方面是比较统一的,tab导航栏使用<scroll-view>标签,内容使用<swiper>,其中的使用方法和参数希望自行参考api文档,不过多解释

布局代码如下:

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
        });
    }
})

页面代码如上面三部分,可以直接新建一项目进行测试

效果图如下

注意事项

在处理顶部tab导航跟随底部页面滑动的时候遇到一个问题,就是在给<scroll-view>中的scrll-left赋值的时候遇到的问题

逻辑上讲初始时tab导航下标小于2时导航栏不滚动,当大于2时向左滑动,以使被选中的导航栏居中,但是当最左侧的选项因为左滑看不到后,我又点击左侧选项希望导航往右滑动,能够看到左边的导航,按上面的js代码计算scroll-left会产生负值,但是scroll-left即使为负值,但是滚动条不会向左缩进去,所以即使为负值,相当于为0,当时做的时候一直在思考这个怎么用逻辑解决,想着要写各种判断,计算距离,结果到最后一句代码直接赋值就搞定了,也是很无语。

小结

以上只是测试demo,可做参考,如有同学通过这个demo引入数据并且成功的话或者失败的话,欢迎沟通探讨!!!

原文地址:https://www.cnblogs.com/xubao/p/12037952.html

时间: 2024-08-28 11:11:34

微信小程序tab切换,可滑动切换,导航栏跟随滚动实现的相关文章

微信小程序--仿京东UI样式顶部导航栏

我们先来看看京东的效果 分析 上端导航栏可以放置多个分类,可滑动 点击导航栏最右端按钮可以查看所有分类,同时背景模糊 内容部分右拉跳转到另外的分类 点击分类时导航栏的滑动部分自动滑动到合适的位置 我的实现 代码展示: js /** * categoryView.js - 分类页面 */ var fakeData = require('../../common/fakeData.js') Page( { data: { categories: ['全部'], currentTab: 0, scro

小程序自定义单页面、全局导航栏

摘要: 小程序开发技巧. 作者:小白 原文:小程序自定义单页面.全局导航栏 Fundebug经授权转载,版权归原作者所有. 需求 产品说小程序返回到首页不太方便,想添加返回首页按钮,UI说导航栏能不能设置背景图片,因为那样设计挺好看的. 需求分析并制定方案 这产品和UI都提需求了,咱也不能反驳哈,所以开始调研,分析可行性方案:1.可以添加悬浮按钮.2.自定义导航栏. 添加悬浮按钮,是看起来是比较简单哈,但是感觉不太优雅,会占据页面的空间,体验也不太好.所以想了下第二种方案,自定义导航栏既可以实现

微信小程序-隐藏和显示自定义的导航

微信小程序中不能直接操作window对象,document文档,跟html的树结构不相同. 实现类似导航的隐藏显示,如图效果: 点击网络显示或隐藏网络中包含的内容.其他类似. 如果是jquery很方便实现,能直接操作document.在微信小程序中实现思路是:在逻辑层定义变量,通过setData赋值. 方法一:通过变量直接赋值,给每一个要控制显示的view定义变量 .wxml 代码: <!--index.wxml--> <view class="navView" bi

微信小程序-tab标签栏实现教程

一.摘要 tab栏(标签切换栏)是app中常见的一种交互方式,它可以承载更多的内容,同时又兼顾友好体验的优点.但在小程序中,官方并没有为咱们提供现成的组件.因此我们程序员展现才艺的时候到了(其实市面上的ui库也做了这个组件).今天咱们就来实现一个对用户更加友好的tab栏,让用户“一点”就停不下来,起到解压的功效~~! 废话不多说,先上效果图. 不瞒您说,这东西我能点一天^^.言归正传,由于tab栏用的地方很多,所以需要封装成组件,因此没有开发或者没用过组件的同志请瞧一瞧官方文档.我之前也写过一篇

微信小程序tab栏切换

index.wxml <text data-current="0" class="{{currentTab == 0? 'active' : ''}}">消息</text> <text data-current="1" class="{{currentTab == 1 ? 'active' : ''}}">通知</text> <view hidden="{{isS

微信小程序自制scroll-view横向滑动滚动条

效果图   实现代码 index.wxml <scroll-view scroll-x="true" class="scroll-view-x" style="padding-top:10rpx" scroll-with-animation="true" wx:if="{{tlist[currentTab].secondList}}" scroll-left='0' bindscroll="

【微信小程序】:实现轮播图3秒滚动

wxml模板:(数据一维数组) <scroll-view scroll-y="true"> <swiper autoplay="auto" interval="3000" duration="500"> <block wx:for="{{home_pics}}" wx:for-index="index"> <swiper-item> <

微信小程序--图片相关问题合辑

图片上传相关文章 微信小程序多张图片上传功能 微信小程序开发(二)图片上传 微信小程序上传一或多张图片 微信小程序实现选择图片九宫格带预览 ETL:微信小程序之图片上传 微信小程序wx.previewImage预览图片 微信小程序之预览图片 小程序开发:上传图片到腾讯云 .NET开发微信小程序-上传图片到服务器 微信小程序本地图片处理--按屏幕尺寸插入图片 [微信小程序]上传图片到阿里云OSS Python Flask小程序文件(图片)上传技巧 小程序图片上传阿里OSS使用方法 微信小程序问题汇

微信小程序学习指南

作者:初雪链接:https://www.zhihu.com/question/50907897/answer/128494332来源:知乎著作权归作者所有.商业转载请联系作者获得授权,非商业转载请注明出处. 微信小程序正式公测, 张小龙全面阐述小程序,定档1月9日上线(附90分钟演讲全文) ... 前言:新人第一坑,跳坑指南:修改后,必须保存:ctrl+S: 1:官方工具:https://mp.weixin.qq.com/debug/w ... tml?t=1476434678461 2:简易教