mirror of
https://gitee.com/vant-contrib/vant-weapp.git
synced 2025-09-10 23:09:45 +08:00
[improvement] Tabs:sticky实现优化,不依赖外层的scrollTop (#1197)
This commit is contained in:
parent
96c2a3af76
commit
f5306b88c1
@ -3,8 +3,7 @@ import Page from '../../common/page';
|
|||||||
Page({
|
Page({
|
||||||
data: {
|
data: {
|
||||||
tabs: [1, 2, 3, 4],
|
tabs: [1, 2, 3, 4],
|
||||||
tabsMore: [1, 2, 3, 4, 5, 6, 7, 8],
|
tabsMore: [1, 2, 3, 4, 5, 6, 7, 8]
|
||||||
scrollTop: 0
|
|
||||||
},
|
},
|
||||||
|
|
||||||
onClickDisabled(event) {
|
onClickDisabled(event) {
|
||||||
@ -26,11 +25,5 @@ Page({
|
|||||||
title: `点击标签 ${event.detail.index + 1}`,
|
title: `点击标签 ${event.detail.index + 1}`,
|
||||||
icon: 'none'
|
icon: 'none'
|
||||||
});
|
});
|
||||||
},
|
|
||||||
|
|
||||||
onPageScroll(event) {
|
|
||||||
this.setData({
|
|
||||||
scrollTop: event.scrollTop
|
|
||||||
});
|
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
@ -87,7 +87,7 @@
|
|||||||
</demo-block>
|
</demo-block>
|
||||||
|
|
||||||
<demo-block title="粘性布局">
|
<demo-block title="粘性布局">
|
||||||
<van-tabs sticky scroll-top="{{ scrollTop }}">
|
<van-tabs sticky>
|
||||||
<van-tab
|
<van-tab
|
||||||
wx:for="1234"
|
wx:for="1234"
|
||||||
wx:key="index"
|
wx:key="index"
|
||||||
|
@ -179,7 +179,6 @@ Page({
|
|||||||
| swipeable | 是否开启手势滑动切换 | `Boolean` | `false` |
|
| swipeable | 是否开启手势滑动切换 | `Boolean` | `false` |
|
||||||
| sticky | 是否使用粘性定位布局 | `Boolean` | `false` |
|
| sticky | 是否使用粘性定位布局 | `Boolean` | `false` |
|
||||||
| offset-top | 粘性定位布局下与顶部的最小距离,单位 px | `Number` | `0` |
|
| offset-top | 粘性定位布局下与顶部的最小距离,单位 px | `Number` | `0` |
|
||||||
| scroll-top | 页面的`scrollTop`,粘性布局下必须要传入,单位 px | `Number` | `0` |
|
|
||||||
|
|
||||||
### Tab API
|
### Tab API
|
||||||
|
|
||||||
|
@ -63,11 +63,7 @@ VantComponent({
|
|||||||
type: Number,
|
type: Number,
|
||||||
value: 0
|
value: 0
|
||||||
},
|
},
|
||||||
swipeable: Boolean,
|
swipeable: Boolean
|
||||||
scrollTop: {
|
|
||||||
type: Number,
|
|
||||||
value: 0
|
|
||||||
}
|
|
||||||
},
|
},
|
||||||
|
|
||||||
data: {
|
data: {
|
||||||
@ -90,7 +86,6 @@ VantComponent({
|
|||||||
lineWidth: 'setLine',
|
lineWidth: 'setLine',
|
||||||
active: 'setActiveTab',
|
active: 'setActiveTab',
|
||||||
animated: 'setTrack',
|
animated: 'setTrack',
|
||||||
scrollTop: 'onScroll',
|
|
||||||
offsetTop: 'setWrapStyle'
|
offsetTop: 'setWrapStyle'
|
||||||
},
|
},
|
||||||
|
|
||||||
@ -102,6 +97,12 @@ VantComponent({
|
|||||||
this.setLine();
|
this.setLine();
|
||||||
this.setTrack();
|
this.setTrack();
|
||||||
this.scrollIntoView();
|
this.scrollIntoView();
|
||||||
|
this.observerTabScroll();
|
||||||
|
this.observerContentScroll();
|
||||||
|
},
|
||||||
|
|
||||||
|
destroyed() {
|
||||||
|
wx.createIntersectionObserver(this).disconnect();
|
||||||
},
|
},
|
||||||
|
|
||||||
methods: {
|
methods: {
|
||||||
@ -310,39 +311,55 @@ VantComponent({
|
|||||||
});
|
});
|
||||||
},
|
},
|
||||||
|
|
||||||
// adjust tab position
|
observerTabScroll() {
|
||||||
onScroll(scrollTop) {
|
|
||||||
if (!this.data.sticky) return;
|
if (!this.data.sticky) return;
|
||||||
|
|
||||||
const { offsetTop } = this.data;
|
const { offsetTop } = this.data;
|
||||||
|
wx.createIntersectionObserver(this, {
|
||||||
|
thresholds: [1]
|
||||||
|
}).relativeToViewport().observe('.van-tabs', result => {
|
||||||
|
const { top } = result.boundingClientRect;
|
||||||
|
let position = '';
|
||||||
|
|
||||||
this.getRect('.van-tabs').then(rect => {
|
if (offsetTop > top) {
|
||||||
const { top, height } = rect;
|
position = 'top';
|
||||||
|
}
|
||||||
|
|
||||||
this.getRect('.van-tabs__wrap').then(rect => {
|
this.$emit('scroll', {
|
||||||
const { height: wrapHeight } = rect;
|
scrollTop: top + offsetTop,
|
||||||
let position = '';
|
isFixed: position === 'top'
|
||||||
|
|
||||||
if (offsetTop > top + height - wrapHeight) {
|
|
||||||
position = 'bottom';
|
|
||||||
} else if (offsetTop > top) {
|
|
||||||
position = 'top';
|
|
||||||
}
|
|
||||||
|
|
||||||
this.$emit('scroll', {
|
|
||||||
scrollTop: scrollTop + offsetTop,
|
|
||||||
isFixed: position === 'top'
|
|
||||||
});
|
|
||||||
|
|
||||||
if (position !== this.data.position) {
|
|
||||||
this.set({
|
|
||||||
position
|
|
||||||
}, () => {
|
|
||||||
this.setWrapStyle();
|
|
||||||
});
|
|
||||||
}
|
|
||||||
});
|
});
|
||||||
|
|
||||||
|
this.setPosition(position);
|
||||||
});
|
});
|
||||||
|
},
|
||||||
|
|
||||||
|
observerContentScroll() {
|
||||||
|
if (!this.data.sticky) return;
|
||||||
|
|
||||||
|
const { offsetTop } = this.data;
|
||||||
|
wx.createIntersectionObserver(this).relativeToViewport().observe('.van-tabs__content', result => {
|
||||||
|
const { top } = result.boundingClientRect;
|
||||||
|
let position = '';
|
||||||
|
|
||||||
|
if (result.intersectionRatio <= 0) {
|
||||||
|
position = 'bottom';
|
||||||
|
} else if (offsetTop > top) {
|
||||||
|
position = 'top';
|
||||||
|
}
|
||||||
|
|
||||||
|
this.setPosition(position);
|
||||||
|
});
|
||||||
|
},
|
||||||
|
|
||||||
|
setPosition(position) {
|
||||||
|
if (position !== this.data.position) {
|
||||||
|
this.set({
|
||||||
|
position
|
||||||
|
}, () => {
|
||||||
|
this.setWrapStyle();
|
||||||
|
});
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
Loading…
x
Reference in New Issue
Block a user