JS实现选中的tab点击后移到屏幕中间

适用场景:类目切换,实现左滑右滑,上滑下滑,点击切换不同类目,被选中的类目移动到屏幕中间位置

watch: {
    // 监听被选中的类目标签,使被选中的标签始终在屏幕中间显示
    selectedIndex: {
      handler: function() {
        // 手机屏幕的宽度
        let screenWidth = document.body.clientWidth;
        // tabs元素
        let waterfallTab = document.getElementById("waterfallTab");
        console.log(screenWidth, "手机屏幕的宽度");
        //使用setTimeout是因为不能实时的获取被点击的盒子,每次只能拿到上一次点击的盒子
        setTimeout(() => {
          // 被选中的tab元素
          let active = document.getElementsByClassName("active")[0];
          // 被选中的元素距离屏幕左侧的距离
          let left = active.getBoundingClientRect().left;
          console.log(left, "left");
          //被选中盒子的宽度
          let activeDivW = active.offsetWidth;
          console.log(activeDivW, "被选中盒子的宽度");
          // 应该居中的距离
          let centerWidth = (screenWidth - activeDivW) / 2;
          console.log(centerWidth, "应该居中的距离");
          // 被选中盒子应该移动的距离
          let moveWidth = left - centerWidth;
          console.log(moveWidth, "被选中盒子应该移动的距离");
          // tabs元素应该移动的距离
          waterfallTab.scrollLeft += moveWidth;
        });
      },
    },
  },
  • 3
    点赞
  • 6
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
实现tab自动居中屏幕显示,并且循环滚动,可以使用 `scroll-view` 组件,并且在点tab时,计算出当前tab的位置,然后通过设置 `scroll-view` 的 `scroll-left` 属性来实现滚动到当前tab居中的效果。同时,可以通过监听 `scroll-view` 的滚动事件来实现循环滚动。 以下是一个示例: ```html <scroll-view scroll-x style="white-space: nowrap;" bindscroll="onScroll"> <div wx:for="{{tabs}}" wx:key="index" style="display: inline-block; margin-right: 20px;" data-index="{{index}}" bindtap="onTabClick">{{item}}</div> </scroll-view> ``` 在这个示例中,`scroll-view` 设置了 `scroll-x` 属性来实现横向滚动,同时设置了 `white-space: nowrap` 属性来让列表项不换行。每个列表项使用 `display: inline-block` 属性来让它们在同一行显示,并通过设置 `margin-right` 来制定它们之间的间距。通过 `wx:for` 循环渲染出tab列表,并通过 `bindtap` 绑定点事件 `onTabClick`。 接下来实现 `onTabClick` 方法: ```javascript onTabClick(e) { const index = e.currentTarget.dataset.index; this.setData({ activeIndex: index, scrollLeft: this.calcScrollLeft(index) }); }, calcScrollLeft(index) { const query = wx.createSelectorQuery().in(this); query.select(`#tab_${index}`).boundingClientRect(); query.select('#scroll-view').boundingClientRect(); query.select('#scroll-view').scrollOffset(); return new Promise((resolve) => { query.exec((res) => { const tabRect = res[0]; const scrollRect = res[1]; const scrollOffset = res[2]; const offsetLeft = tabRect.left + tabRect.width / 2 - scrollRect.width / 2; resolve(scrollOffset.scrollLeft + offsetLeft); }); }); } ``` 在 `onTabClick` 方法中,通过 `e.currentTarget.dataset.index` 获取当前点tab的索引,然后通过 `calcScrollLeft` 方法计算出当前tab居中时,`scroll-view` 的 `scroll-left` 值,并设置到页面的数据中。 接下来实现 `calcScrollLeft` 方法。该方法通过 `wx.createSelectorQuery` 创建一个选择器对象,然后通过 `query.select` 方法选择当前点tab和 `scroll-view` 组件,并通过 `boundingClientRect` 方法获取它们的位置和大小信息。最后,根据这些信息计算出当前tab居中时,`scroll-view` 的 `scroll-left` 值,并返回一个 Promise 对象。 最后,实现循环滚动: ```javascript onScroll(e) { const query = wx.createSelectorQuery().in(this); query.select('#scroll-view').boundingClientRect(); query.selectAll('.tab-item').boundingClientRect(); query.exec((res) => { const scrollRect = res[0]; const tabRects = res[1]; const scrollLeft = e.detail.scrollLeft; const activeIndex = this.data.activeIndex; if (scrollLeft < tabRects[0].left - scrollRect.width / 2) { this.setData({ activeIndex: (activeIndex + tabRects.length - 1) % tabRects.length, scrollLeft: this.calcScrollLeft((activeIndex + tabRects.length - 1) % tabRects.length) }); } else if (scrollLeft > tabRects[tabRects.length - 1].left + tabRects[tabRects.length - 1].width - scrollRect.width / 2) { this.setData({ activeIndex: (activeIndex + 1) % tabRects.length, scrollLeft: this.calcScrollLeft((activeIndex + 1) % tabRects.length) }); } }); } ``` 在 `onScroll` 方法中,通过 `wx.createSelectorQuery` 创建一个选择器对象,然后选择 `scroll-view` 和所有的tab元素,并通过 `boundingClientRect` 方法获取它们的位置和大小信息。然后根据 `scroll-view` 的 `scroll-left` 值和tab元素的位置信息,判断当前是否需要循环滚动,并通过 `setData` 方法更新数据。 注意:在模板中,需要给每个tab元素加上一个 `class`,例如:`.tab-item`,然后在 `onScroll` 方法中通过 `query.selectAll('.tab-item')` 选择所有的tab元素。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值