mirror of
https://gitee.com/vant-contrib/vant.git
synced 2025-04-06 03:57:59 +08:00
feat(Tab): improve scrollLeftTo performance
This commit is contained in:
parent
e9369acf26
commit
f8a3669f2d
@ -205,7 +205,7 @@ In scrollspy mode, the list of content will be tiled
|
|||||||
| sticky | Whether to use sticky mode | *boolean* | `false` | - |
|
| sticky | Whether to use sticky mode | *boolean* | `false` | - |
|
||||||
| swipeable | Whether to switch tabs with swipe gestrue in the content | *boolean* | `false` | - |
|
| swipeable | Whether to switch tabs with swipe gestrue in the content | *boolean* | `false` | - |
|
||||||
| lazy-render | Whether to enable tab content lazy render | *boolean* | `true` | - |
|
| lazy-render | Whether to enable tab content lazy render | *boolean* | `true` | - |
|
||||||
| scrollspy | Whether to use scrollspy mode | *boolean* | `false` | - |
|
| scrollspy | Whether to use scrollspy mode | *boolean* | `false` | 2.3.0 |
|
||||||
|
|
||||||
### Tab Props
|
### Tab Props
|
||||||
|
|
||||||
|
@ -209,7 +209,7 @@ export default {
|
|||||||
| sticky | 是否使用粘性定位布局 | *boolean* | `false` | - |
|
| sticky | 是否使用粘性定位布局 | *boolean* | `false` | - |
|
||||||
| swipeable | 是否开启手势滑动切换 | *boolean* | `false` | - |
|
| swipeable | 是否开启手势滑动切换 | *boolean* | `false` | - |
|
||||||
| lazy-render | 是否开启标签页内容延迟渲染 | *boolean* | `true` | - |
|
| lazy-render | 是否开启标签页内容延迟渲染 | *boolean* | `true` | - |
|
||||||
| scrollspy | 是否开启滚动导航 | *boolean* | `false` | - |
|
| scrollspy | 是否开启滚动导航 | *boolean* | `false` | 2.3.0 |
|
||||||
|
|
||||||
### Tab Props
|
### Tab Props
|
||||||
|
|
||||||
|
@ -45,12 +45,12 @@ export default createComponent({
|
|||||||
},
|
},
|
||||||
|
|
||||||
render(h) {
|
render(h) {
|
||||||
const { slots, isActive } = this;
|
const { slots, parent, isActive } = this;
|
||||||
const shouldRender = this.inited || this.parent.scrollspy || !this.parent.lazyRender;
|
const shouldRender = this.inited || parent.scrollspy || !parent.lazyRender;
|
||||||
const show = this.parent.scrollspy || isActive;
|
const show = parent.scrollspy || isActive;
|
||||||
const Content = shouldRender ? slots() : h();
|
const Content = shouldRender ? slots() : h();
|
||||||
|
|
||||||
if (this.parent.animated) {
|
if (parent.animated) {
|
||||||
return (
|
return (
|
||||||
<div
|
<div
|
||||||
role="tabpanel"
|
role="tabpanel"
|
||||||
|
@ -6,7 +6,13 @@ import { on, off } from '../utils/dom/event';
|
|||||||
import { ParentMixin } from '../mixins/relation';
|
import { ParentMixin } from '../mixins/relation';
|
||||||
import { BindEventMixin } from '../mixins/bind-event';
|
import { BindEventMixin } from '../mixins/bind-event';
|
||||||
import { BORDER_TOP_BOTTOM } from '../utils/constant';
|
import { BORDER_TOP_BOTTOM } from '../utils/constant';
|
||||||
import { setRootScrollTop, getElementTop, getVisibleHeight, getVisibleTop } from '../utils/dom/scroll';
|
import {
|
||||||
|
setRootScrollTop,
|
||||||
|
getElementTop,
|
||||||
|
getVisibleHeight,
|
||||||
|
getVisibleTop
|
||||||
|
} from '../utils/dom/scroll';
|
||||||
|
|
||||||
import Title from './Title';
|
import Title from './Title';
|
||||||
import Content from './Content';
|
import Content from './Content';
|
||||||
import Sticky from '../sticky';
|
import Sticky from '../sticky';
|
||||||
@ -19,7 +25,7 @@ export default createComponent({
|
|||||||
BindEventMixin(function(bind) {
|
BindEventMixin(function(bind) {
|
||||||
bind(window, 'resize', this.resize, true);
|
bind(window, 'resize', this.resize, true);
|
||||||
if (this.scrollspy) {
|
if (this.scrollspy) {
|
||||||
bind(window, 'scroll', this.onScrollspyScroll, true);
|
bind(window, 'scroll', this.onScroll, true);
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
],
|
],
|
||||||
@ -142,9 +148,9 @@ export default createComponent({
|
|||||||
|
|
||||||
scrollspy(val) {
|
scrollspy(val) {
|
||||||
if (val) {
|
if (val) {
|
||||||
on(window, 'scroll', this.onScrollspyScroll, true);
|
on(window, 'scroll', this.onScroll, true);
|
||||||
} else {
|
} else {
|
||||||
off(window, 'scroll', this.onScrollspyScroll);
|
off(window, 'scroll', this.onScroll);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
@ -277,7 +283,7 @@ export default createComponent({
|
|||||||
scrollLeftTo(nav, to, immediate ? 0 : this.duration);
|
scrollLeftTo(nav, to, immediate ? 0 : this.duration);
|
||||||
},
|
},
|
||||||
|
|
||||||
onScroll(params) {
|
onSticktScroll(params) {
|
||||||
this.stickyFixed = params.isFixed;
|
this.stickyFixed = params.isFixed;
|
||||||
this.$emit('scroll', params);
|
this.$emit('scroll', params);
|
||||||
},
|
},
|
||||||
@ -296,7 +302,7 @@ export default createComponent({
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
|
||||||
onScrollspyScroll() {
|
onScroll() {
|
||||||
if (this.scrollspy && !this.clickedScroll) {
|
if (this.scrollspy && !this.clickedScroll) {
|
||||||
const index = this.getCurrentIndexOnScroll();
|
const index = this.getCurrentIndexOnScroll();
|
||||||
this.setCurrentIndex(index);
|
this.setCurrentIndex(index);
|
||||||
@ -304,20 +310,17 @@ export default createComponent({
|
|||||||
},
|
},
|
||||||
|
|
||||||
getCurrentIndexOnScroll() {
|
getCurrentIndexOnScroll() {
|
||||||
let i;
|
const { children } = this;
|
||||||
|
|
||||||
for (i = 0; i < this.children.length; i++) {
|
for (let index = 0; index < children.length; index++) {
|
||||||
const top = getVisibleTop(this.children[i].$el);
|
const top = getVisibleTop(children[index].$el);
|
||||||
|
|
||||||
if (top > this.scrollOffset) {
|
if (top > this.scrollOffset) {
|
||||||
if (i === 0) {
|
return index === 0 ? 0 : index - 1;
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
return i - 1;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return i - 1;
|
return children.length - 1;
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
|
||||||
@ -381,7 +384,7 @@ export default createComponent({
|
|||||||
<Sticky
|
<Sticky
|
||||||
container={this.$el}
|
container={this.$el}
|
||||||
offsetTop={this.offsetTop}
|
offsetTop={this.offsetTop}
|
||||||
onScroll={this.onScroll}
|
onScroll={this.onSticktScroll}
|
||||||
>
|
>
|
||||||
{Wrap}
|
{Wrap}
|
||||||
</Sticky>
|
</Sticky>
|
||||||
|
@ -1,7 +1,11 @@
|
|||||||
import { raf } from '../utils/dom/raf';
|
import { raf, cancelRaf } from '../utils/dom/raf';
|
||||||
import { getRootScrollTop, setRootScrollTop } from '../utils/dom/scroll';
|
import { getRootScrollTop, setRootScrollTop } from '../utils/dom/scroll';
|
||||||
|
|
||||||
|
let scrollLeftRafId: number;
|
||||||
|
|
||||||
export function scrollLeftTo(el: HTMLElement, to: number, duration: number) {
|
export function scrollLeftTo(el: HTMLElement, to: number, duration: number) {
|
||||||
|
cancelRaf(scrollLeftRafId);
|
||||||
|
|
||||||
let count = 0;
|
let count = 0;
|
||||||
const from = el.scrollLeft;
|
const from = el.scrollLeft;
|
||||||
const frames = duration === 0 ? 1 : Math.round((duration * 1000) / 16);
|
const frames = duration === 0 ? 1 : Math.round((duration * 1000) / 16);
|
||||||
@ -10,7 +14,7 @@ export function scrollLeftTo(el: HTMLElement, to: number, duration: number) {
|
|||||||
el.scrollLeft += (to - from) / frames;
|
el.scrollLeft += (to - from) / frames;
|
||||||
|
|
||||||
if (++count < frames) {
|
if (++count < frames) {
|
||||||
raf(animate);
|
scrollLeftRafId = raf(animate);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -19,20 +23,20 @@ export function scrollLeftTo(el: HTMLElement, to: number, duration: number) {
|
|||||||
|
|
||||||
export function scrollTopTo(to: number, duration: number, cb: Function) {
|
export function scrollTopTo(to: number, duration: number, cb: Function) {
|
||||||
let current = getRootScrollTop();
|
let current = getRootScrollTop();
|
||||||
const toDown = current < to;
|
const isDown = current < to;
|
||||||
const frames = duration === 0 ? 1 : Math.round((duration * 1000) / 16);
|
const frames = duration === 0 ? 1 : Math.round((duration * 1000) / 16);
|
||||||
const pxPerFrames = (to - current) / frames;
|
const step = (to - current) / frames;
|
||||||
|
|
||||||
function animate() {
|
function animate() {
|
||||||
current += pxPerFrames;
|
current += step;
|
||||||
|
|
||||||
if ((toDown && current > to) || (!toDown && current < to)) {
|
if ((isDown && current > to) || (!isDown && current < to)) {
|
||||||
current = to;
|
current = to;
|
||||||
}
|
}
|
||||||
|
|
||||||
setRootScrollTop(current);
|
setRootScrollTop(current);
|
||||||
|
|
||||||
if ((toDown && current < to) || (!toDown && current > to)) {
|
if ((isDown && current < to) || (!isDown && current > to)) {
|
||||||
raf(animate);
|
raf(animate);
|
||||||
} else {
|
} else {
|
||||||
cb && cb();
|
cb && cb();
|
||||||
|
Loading…
x
Reference in New Issue
Block a user