小程序 和 uni-app 实现tab点击自动居中屏幕显示,并且循环滚动
时间: 2024-03-06 21:47:35 浏览: 204
Android tab 栏居中滚动
5星 · 资源好评率100%
要实现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元素。
阅读全文