From 0993b394b16fdbf92bdf02d39090e631bba1f471 Mon Sep 17 00:00:00 2001 From: chenjiahan Date: Sat, 29 Feb 2020 15:57:20 +0800 Subject: [PATCH] fix(Tabs): incorrect scrollspy position while inside a scroller --- src/tabs/index.js | 12 +++++++----- src/tabs/utils.ts | 18 ++++++++++++------ src/utils/dom/scroll.ts | 8 +++++--- 3 files changed, 24 insertions(+), 14 deletions(-) diff --git a/src/tabs/index.js b/src/tabs/index.js index ca688facd..c11d02585 100644 --- a/src/tabs/index.js +++ b/src/tabs/index.js @@ -300,12 +300,14 @@ export default createComponent({ scrollToCurrentContent() { if (this.scrollspy) { - this.clickedScroll = true; - const instance = this.children[this.currentIndex]; - const el = instance && instance.$el; + const target = this.children[this.currentIndex]; + const el = target?.$el; + if (el) { - const to = Math.ceil(getElementTop(el)) - this.scrollOffset; - scrollTopTo(to, +this.duration, () => { + const to = getElementTop(el, this.scroller) - this.scrollOffset; + + this.clickedScroll = true; + scrollTopTo(this.scroller, to, +this.duration, () => { this.clickedScroll = false; }); } diff --git a/src/tabs/utils.ts b/src/tabs/utils.ts index 42cdbed65..e7ff9c71b 100644 --- a/src/tabs/utils.ts +++ b/src/tabs/utils.ts @@ -1,5 +1,5 @@ import { raf, cancelRaf } from '../utils/dom/raf'; -import { getRootScrollTop, setRootScrollTop } from '../utils/dom/scroll'; +import { getScrollTop, setScrollTop } from '../utils/dom/scroll'; let scrollLeftRafId: number; @@ -21,8 +21,14 @@ export function scrollLeftTo(el: HTMLElement, to: number, duration: number) { animate(); } -export function scrollTopTo(to: number, duration: number, cb: Function) { - let current = getRootScrollTop(); +export function scrollTopTo( + el: HTMLElement, + to: number, + duration: number, + callback: Function +) { + let current = getScrollTop(el); + const isDown = current < to; const frames = duration === 0 ? 1 : Math.round((duration * 1000) / 16); const step = (to - current) / frames; @@ -34,12 +40,12 @@ export function scrollTopTo(to: number, duration: number, cb: Function) { current = to; } - setRootScrollTop(current); + setScrollTop(el, current); if ((isDown && current < to) || (!isDown && current > to)) { raf(animate); - } else { - cb && cb(); + } else if (callback) { + callback(); } } diff --git a/src/utils/dom/scroll.ts b/src/utils/dom/scroll.ts index cd3fc68bd..9d59c149c 100644 --- a/src/utils/dom/scroll.ts +++ b/src/utils/dom/scroll.ts @@ -65,12 +65,14 @@ export function setRootScrollTop(value: number) { setScrollTop(document.body, value); } -// get distance from element top to page top -export function getElementTop(el: ScrollElement) { +// get distance from element top to page top or scroller top +export function getElementTop(el: ScrollElement, scroller?: HTMLElement) { if (isWindow(el)) { return 0; } - return el.getBoundingClientRect().top + getRootScrollTop(); + + const scrollTop = scroller ? getScrollTop(scroller) : getRootScrollTop(); + return el.getBoundingClientRect().top + scrollTop; } export function getVisibleHeight(el: ScrollElement) {