岁寒之松柏:小程序如何实现IndexBar

前言

本文主要阐述用小程序的原生API如何实现一个IndexBar,当然本文使用的思路只是笔者想到的方法,如果有更好的方法欢迎在评论区指正。

简单实现

什么是IndexBar

我想大家在开发一定遇到过这种需求

左边是一个类似导航的东西,右边是一个轮动条,需要用户在点击左边导航的时候,右边自动滚动到指定位置,右边滚动条轮动的时候需要左右的导航自动选中标题。总体来说逻辑还是比较简单的。从上述需求也很容易得出实现这个东西总体需要两个核心逻辑

  • 实现点击导航栏 滚动视图自动滚动到指定位置
  • 实现滚动滚条 标题栏自动切换

实现视图根据标题自动滚动

在小程序中实现这个功能我们有两个方法

  • 通过动态设置scroll-view的scroll-into-view 属性
  • 通过获取scroll-view的context 执行如下方法

本项目使用第一种方法实现,第二种方式读者可以自己尝试一下 核心思路如下

  1. 在js代码中设置intoViewIdactive 属性分别控制要跳转的scroll-view子视图和当前激活状态的index按钮 并创建changeActive方法用于实现按钮控制scroll-view
  2. 在wxml中绑定intoViewId 与设置changeActive事件

以下时核心代码

JS核心代码

js 复制代码
Page({

  /**
   * 页面的初始数据
   */
  data: {
    // 用于绑定视图id
    intoViewId:"",
    // 用于设置当前处于激活状态的按钮
    active:0,
    categraylist:[{
      name:"推荐",
    },{
      name:"拿铁",
    },{
      name:"美式",
    },{
      name:"摩卡",
    }],
  },
  
  // 修改当前处于激活状态的导航 并 设置scroll需要进入viewId
  changeActive(e){
    const index = e.currentTarget.dataset.index
    this.setData({
      active:index
    })
    this.setData({
      intoViewId:`id-${index}`
    })
  },
})

wxml代码

html 复制代码
<view class="page">
  <view class="top-bar">
  </view>
  <view class="list">
    <view class="left-warpper">
      <block wx:for="{{categraylist}}" wx:key="name">
         <!--设置点击左边框事件 并把当前点击的索引传入 -->
        <view data-index="{{index}}" bind:tap="changeActive" class="btn {{active == index ? 'active' :'' }}">{{item.name}}</view>
      </block>

    </view>
   <!--scroll-into-view 绑定需要跳转的id  scroll-with-animation 启用动画  -->  
    <scroll-view 
      class="coffee-warpper" 
      scroll-into-view="{{intoViewId}}" 
      scroll-with-animation     
      scroll-y>
      <block wx:for="{{categraylist}}" wx:key="name">
        <!-- 为scroll-view子元素设置id -->
        <view id="id-{{index}}" class="coffee-container">
          <view class="title">{{item.name}}</view>
          <block wx:for="{{item.itemList}}" wx:for-item="itm" wx:key="name">
            <coffee-item item="{{itm}}"></coffee-item>
          </block>
        </view>
      </block>
      <view class="blank"></view>
    </scroll-view>
  </view>
</view>  

实现滚动滚动条 标题栏自动切换

实现这个功能 小程序并没有提供现成api 让我们可以绑定scroll-view上的事件就可以实现对scroll-view的监听虽然确实有一个绑定滚动监听的事件但是并没有满足我们需求,不过我们可以使用其他的API实现对scroll状态的监听 比如wx.createIntersectionObserver 这个API主要用来判断子元素是否进入父元素或者离开父元素,我们可以根据这个机制,实现对父元素中子元素的记录具体思路如下:

  • 初始化一个Set保存子视图id
  • 当事件触发时判断Set是否包含子视图id
    • 如果不包含说明第一次触犯 说明是进入视图 把id加入Set
    • 如果包含说明第二次触犯 说明是离开入视图 把id从Set中删除
  • 遍历Set得到最小的id索引就是当前需要激活的侧边栏id索引

根据上面的思路我们可以只需要在js的代码中添加如下代码就可以实现需要的功能

js 复制代码
   // 用于保存当前在视图中视图id
   let idSet = new Set()
   Page({
    
    onReady() {
    this._observer = wx.createIntersectionObserver(this,{
      observeAll:true
    })
    this._observer
      .relativeTo('.coffee-warpper',{top:1})
      .observe('.coffee-container', (res) => {
         
         if(idSet.has(res.id)){
          // 当前存在的这个VIEWID 
          // 说明scroll-view视图中存在这个子视图 
          // 再次触犯说明这个子视图 离开了scroll-view
          idSet.delete(res.id)
          let ids =  Array.from(idSet).map(item=>{
              return Number(item.replace("id-",""))
          })
          let min = Math.min(...ids)
          this.setData({
            active:min
          })
         }else{
          idSet.add(res.id)
         }
      })
  
  },
   
   })
相关推荐
Mr Xu_2 分钟前
Vue 3 中 watch 的使用详解:监听响应式数据变化的利器
前端·javascript·vue.js
未来龙皇小蓝5 分钟前
RBAC前端架构-01:项目初始化
前端·架构
程序员agions14 分钟前
2026年,微前端终于“死“了
前端·状态模式
万岳科技系统开发14 分钟前
食堂采购系统源码库存扣减算法与并发控制实现详解
java·前端·数据库·算法
程序员猫哥_22 分钟前
HTML 生成网页工具推荐:从手写代码到 AI 自动生成网页的进化路径
前端·人工智能·html
龙飞0522 分钟前
Systemd -systemctl - journalctl 速查表:服务管理 + 日志排障
linux·运维·前端·chrome·systemctl·journalctl
我爱加班、、28 分钟前
Websocket能携带token过去后端吗
前端·后端·websocket
AAA阿giao28 分钟前
从零拆解一个 React + TypeScript 的 TodoList:模块化、数据流与工程实践
前端·react.js·ui·typescript·前端框架
杨超越luckly34 分钟前
HTML应用指南:利用GET请求获取中国500强企业名单,揭秘企业增长、分化与转型的新常态
前端·数据库·html·可视化·中国500强
hedley(●'◡'●)1 小时前
基于cesium和vue的大疆司空模仿程序
前端·javascript·vue.js·python·typescript·无人机