移动端菜单点击效果,点击当前元素展示到可视区

以微信小程序为例

wxml
<scroll-view
  class="scroll-menu"
  scroll-left="{{scrollLeft}}"
  scroll-x="{{true}}"
  scroll-with-animation="{{true}}"
  enable-flex="{{true}}">
  <view
    class="menu-item {{selectedIndex === index && 'activeMenu'}}"
    wx:for="{{menuList}}"
    wx:key="index"
    data-index="{{index}}"
    bindtap="handleTap">
    {{item.name}}
  </view>
</scroll-view>
js
// pages/menu/menu.js
Page({

  /**
   * 页面的初始数据
   */
  data: {
    // 菜单数据
    menuList: [
      { name: "全部分类" },
      { name: "拼团" },
      { name: "限时" },
      { name: "新人" },
      { name: "爆品" },
      { name: "日用品" },
      { name: "床上用品" },
      { name: "水果类" },
    ],
    selectedIndex: 0, // 当前点击的菜单索引
    scrollLeft: 0, // 滚动条距离左边的距离
    menuWidth: 0, // 菜单宽度
    menuItemArr: [], // 菜单所有的子项数组
  },
  onReady: function () {
    let _this = this;
    const queryDom = wx.createSelectorQuery().in(_this);
    // 获取菜单整体的宽度
    queryDom
      .select(".scroll-menu")
      .boundingClientRect()
      .exec(function(res) {
        console.log(res);
        _this.setData({
          menuWidth: res[0].width
        });
      });
    // 获取菜单所有子项数据
    let arr = [];
    queryDom
      .selectAll(".menu-item")
      .boundingClientRect()
      .exec(function(res) {
        console.log(res);
        res[1].forEach(item => {
          arr.push({ width: item.width, left: item.left });
        });
        _this.setData({
          menuItemArr: arr
        });
      });
    console.log(_this.data.menuWidth, _this.data.menuItemArr);
  },
  // 事件点击
  handleTap(e) {
    let selectedIndex = e.target.dataset.index; // 点击的当前元素索引
    let selectedItem = this.data.menuItemArr[selectedIndex]; // 点击的当前菜单item数据
    if (selectedItem) {
      // 滚动的距离 = 当前点击元素距离左边的距离-(菜单的宽度-当前点击元素的宽度)/2
      let targetDistance = selectedItem.left - (this.data.menuWidth - selectedItem.width) / 2;
      // 只有距离大于0的时候,需要滚动,否则滚动条还需要在开头
      targetDistance = targetDistance < 0 ? 0 : targetDistance;
      this.setData({
        scrollLeft: targetDistance,
        selectedIndex
      });
    }
  }
})
wxss
.scroll-menu {
  width: 100%;
  height: 40px;
  display: flex;
  flex-wrap: nowrap;
  border-bottom: 2rpx solid #eee;
  padding: 0 20rpx;
  box-sizing: border-box;
}
.menu-item {
  white-space: nowrap;
  display: flex;
  align-items: center;
  margin-right: 40rpx;
}
.activeMenu {
  color: red;
}
效果图

在这里插入图片描述

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值