[bugfix] Tabs:回滚使用IntersectionObserver实现的sticky效果

This commit is contained in:
张敏 2019-01-19 18:50:38 +08:00 committed by rex
parent 7fc0eb7a00
commit 03fa90dd9d
3 changed files with 39 additions and 46 deletions

View File

@ -25,5 +25,11 @@ Page({
title: `点击标签 ${event.detail.index + 1}`,
icon: 'none'
});
},
onPageScroll(event) {
this.setData({
scrollTop: event.scrollTop
});
}
});

View File

@ -87,7 +87,7 @@
</demo-block>
<demo-block title="粘性布局">
<van-tabs sticky>
<van-tabs sticky scroll-top="{{ scrollTop }}">
<van-tab
wx:for="1234"
wx:key="index"
@ -107,7 +107,7 @@
wx:key="index"
title="{{ '标签' + item }}"
>
<view class="content">
<view class="content" style="height: 400px;">
{{ '内容' + item }}
</view>
</van-tab>

View File

@ -67,6 +67,10 @@ VantComponent({
offsetTop: {
type: Number,
value: 0
},
scrollTop: {
type: Number,
value: 0
}
},
@ -91,6 +95,7 @@ VantComponent({
lineHeight: 'setLine',
active: 'setActiveTab',
animated: 'setTrack',
scrollTop: 'onScroll',
offsetTop: 'setWrapStyle'
},
@ -102,8 +107,6 @@ VantComponent({
this.setLine();
this.setTrack();
this.scrollIntoView();
this.observerTabScroll();
this.observerContentScroll();
},
destroyed() {
@ -319,55 +322,39 @@ VantComponent({
});
},
observerTabScroll() {
// adjust tab position
onScroll(scrollTop) {
if (!this.data.sticky) return;
const { offsetTop } = this.data;
wx.createIntersectionObserver(this, {
thresholds: [1]
}).relativeToViewport().observe('.van-tabs', result => {
const { top } = result.boundingClientRect;
let position = '';
if (offsetTop > top) {
position = 'top';
}
this.getRect('.van-tabs').then(rect => {
const { top, height } = rect;
this.$emit('scroll', {
scrollTop: top + offsetTop,
isFixed: position === 'top'
this.getRect('.van-tabs__wrap').then(rect => {
const { height: wrapHeight } = rect;
let position = '';
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();
});
}
}
}
});