[Improment] improve Tab sticky fluency (#388)

This commit is contained in:
neverland 2017-12-07 11:52:55 +08:00 committed by GitHub
parent c2dddeb552
commit 1a0f73b12e
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
5 changed files with 58 additions and 26 deletions

View File

@ -99,7 +99,7 @@ export default {
<style lang="postcss"> <style lang="postcss">
.demo-tab { .demo-tab {
margin-bottom: 1000px; margin-bottom: 700px;
.van-tab__pane { .van-tab__pane {
background-color: #fff; background-color: #fff;
@ -121,5 +121,11 @@ export default {
height: 50px; height: 50px;
line-height: 50px; line-height: 50px;
} }
.van-doc-demo-block:last-child {
.van-tab__pane {
padding: 50px 20px;
}
}
} }
</style> </style>

View File

@ -1,6 +1,9 @@
<template> <template>
<div class="van-tabs" :class="[`van-tabs--${type}`, { 'van-tabs--fixed': fixed }]"> <div class="van-tabs" :class="[`van-tabs--${type}`]">
<div class="van-tabs__wrap" :class="{ 'van-tabs--scrollbale': scrollable, 'van-hairline--top-bottom': type === 'line' }"> <div class="van-tabs__wrap" :class="[`van-tabs__wrap--${position}`, {
'van-tabs--scrollable': scrollable,
'van-hairline--top-bottom': type === 'line'
}]">
<div class="van-tabs__nav" :class="`van-tabs__nav--${type}`" ref="nav"> <div class="van-tabs__nav" :class="`van-tabs__nav--${type}`" ref="nav">
<div v-if="type === 'line'" class="van-tabs__nav-bar" :style="navBarStyle" /> <div v-if="type === 'line'" class="van-tabs__nav-bar" :style="navBarStyle" />
<div <div
@ -57,7 +60,7 @@ export default {
return { return {
tabs: [], tabs: [],
fixed: false, position: 'content-top',
curActive: 0, curActive: 0,
navBarStyle: {} navBarStyle: {}
}; };
@ -92,7 +95,7 @@ export default {
} }
}, },
destoryed() { beforeDestroy() {
/* istanbul ignore next */ /* istanbul ignore next */
if (this.sticky) { if (this.sticky) {
this.scrollHandler(false); this.scrollHandler(false);
@ -111,12 +114,23 @@ export default {
scrollHandler(init) { scrollHandler(init) {
this.scrollEl = this.scrollEl || scrollUtils.getScrollEventTarget(this.$el); this.scrollEl = this.scrollEl || scrollUtils.getScrollEventTarget(this.$el);
this.scrollEl[init ? 'addEventListener' : 'removeEventListener']('scroll', this.onScroll); this.scrollEl[init ? 'addEventListener' : 'removeEventListener']('scroll', this.onScroll);
this.onScroll(); if (init) {
this.onScroll();
}
}, },
// fixed tab when scrollTop > distance to top // adjust tab position
onScroll() { onScroll() {
this.fixed = scrollUtils.getScrollTop(this.scrollEl) > scrollUtils.getElementTop(this.$el); const scrollTop = scrollUtils.getScrollTop(this.scrollEl);
const elTopToPageTop = scrollUtils.getElementTop(this.$el);
const elBottomToPageTop = elTopToPageTop + this.$el.offsetHeight - this.$refs.nav.offsetHeight;
if (scrollTop > elBottomToPageTop) {
this.position = 'content-bottom';
} else if (scrollTop > elTopToPageTop) {
this.position = 'page-top';
} else {
this.position = 'content-top';
}
}, },
// update nav bar style // update nav bar style

View File

@ -85,6 +85,10 @@
display: block; display: block;
width: 100%; width: 100%;
resize: none; resize: none;
&[disabled] {
background-color: transparent;
}
} }
&__icon { &__icon {

View File

@ -7,10 +7,27 @@ $van-tabs-card-height: 28px;
.van-tabs { .van-tabs {
position: relative; position: relative;
&__wrap {
top: 0;
left: 0;
right: 0;
z-index: 1;
position: absolute;
&--page-top {
position: fixed;
}
&--content-bottom {
top: auto;
bottom: 0;
}
}
&__nav { &__nav {
display: flex; display: flex;
position: relative;
user-select: none; user-select: none;
position: relative;
background-color: $white; background-color: $white;
&--line { &--line {
@ -49,13 +66,13 @@ $van-tabs-card-height: 28px;
background-color: $red; background-color: $red;
} }
&--scrollbale { &--scrollable {
.van-tab { .van-tab {
flex: 0 0 22%; flex: 0 0 22%;
} }
.van-tabs__nav { .van-tabs__nav {
overflow-y: auto; overflow-x: auto;
-webkit-overflow-scrolling: touch; -webkit-overflow-scrolling: touch;
&::-webkit-scrollbar { &::-webkit-scrollbar {
@ -65,21 +82,12 @@ $van-tabs-card-height: 28px;
} }
} }
&--fixed { &--line {
.van-tabs__wrap { padding-top: $van-tabs-line-height;
top: 0; }
left: 0;
right: 0;
position: fixed;
}
&.van-tabs--line { &--card {
padding-top: $van-tabs-line-height; padding-top: $van-tabs-card-height;
}
&.van-tabs--card {
padding-top: $van-tabs-card-height;
}
} }
} }

View File

@ -125,7 +125,7 @@ describe('Tabs', () => {
wrapper.vm.sticky = false; wrapper.vm.sticky = false;
setTimeout(() => { setTimeout(() => {
expect(wrapper.vm.$children[0].fixed).to.be.false; expect(wrapper.vm.$children[0].position).to.equal('content-top');
done(); done();
}, 30); }, 30);
}); });