From 88b65773a13eff1b1764a6751fc9d7109ef95e61 Mon Sep 17 00:00:00 2001 From: BeADre Date: Fri, 21 May 2021 20:08:18 +0800 Subject: [PATCH] fix: use ScrollTo method to replace back-top animation --- packages/varlet-ui/src/back-top/BackTop.vue | 36 ++++++++------------- packages/varlet-ui/src/tabs/Tabs.vue | 2 +- packages/varlet-ui/src/utils/elements.ts | 8 +++-- 3 files changed, 19 insertions(+), 27 deletions(-) diff --git a/packages/varlet-ui/src/back-top/BackTop.vue b/packages/varlet-ui/src/back-top/BackTop.vue index 2539331860c..fb2c29daf11 100644 --- a/packages/varlet-ui/src/back-top/BackTop.vue +++ b/packages/varlet-ui/src/back-top/BackTop.vue @@ -13,7 +13,7 @@ import Button from '../button' import Icon from '../icon' import { props } from './props' import { isString, easeInOutCubic, throttle, toNumber } from '../utils/shared' -import { getScrollTop, getScrollLeft, requestAnimationFrame } from '../utils/elements' +import { getScrollTop, getScrollLeft, scrollTo } from '../utils/elements' export default defineComponent({ name: 'VarBackTop', @@ -23,47 +23,37 @@ export default defineComponent({ }, props, setup(props) { - let element: Element | Window = window + let element: HTMLElement | Window = window const show: Ref = ref(false) const click = () => { props.onClick?.() - const top = getScrollTop(element as Element) - const left = getScrollLeft(element as Element) + const left = getScrollLeft(element as HTMLElement) - const startTime = Date.now() - - const frameFunc = () => { - const progress = (Date.now() - startTime) / props.duration - if (progress < 1) { - const nextTop = top * (1 - easeInOutCubic(progress)) - - ;(element as Element).scrollTo(left, nextTop) - requestAnimationFrame(frameFunc) - } else { - ;(element as Element).scrollTo(left, 0) - } - } - requestAnimationFrame(frameFunc) + scrollTo(element, { + left, + duration: props.duration, + animation: easeInOutCubic + }) } const scroll = () => { - show.value = getScrollTop(element as Element) >= toNumber(props.visibilityHeight) + show.value = getScrollTop(element as HTMLElement) >= toNumber(props.visibilityHeight) } const throttleScroll = throttle(scroll, 200) - const getElement = () => { + const getHTMLElement = () => { if (!isString(props.target)) throw Error('[Varlet] BackTop: type of prop "target" should be a string') - + const el = document.querySelector(props.target) if (!el) throw Error('[Varlet] BackTop: "target" should be a selector') - return el + return el as HTMLElement } onMounted(() => { - if (props.target) element = getElement() + if (props.target) element = getHTMLElement() element.addEventListener('scroll', throttleScroll) }) diff --git a/packages/varlet-ui/src/tabs/Tabs.vue b/packages/varlet-ui/src/tabs/Tabs.vue index c740258b566..03344ea0f3a 100644 --- a/packages/varlet-ui/src/tabs/Tabs.vue +++ b/packages/varlet-ui/src/tabs/Tabs.vue @@ -53,7 +53,7 @@ import { import { props } from './props' import { TabsProvider, useTabList } from './provide' import { TabProvider } from '../tab/provide' -import { easeInOutCubic, isNumber, linear } from '../utils/shared' +import { isNumber, linear } from '../utils/shared' import { toSizeUnit, scrollTo } from '../utils/elements' export default defineComponent({ diff --git a/packages/varlet-ui/src/utils/elements.ts b/packages/varlet-ui/src/utils/elements.ts index c4de10c7a4e..75ea55419c0 100644 --- a/packages/varlet-ui/src/utils/elements.ts +++ b/packages/varlet-ui/src/utils/elements.ts @@ -1,4 +1,4 @@ -import { easeInOutCubic, isNumber, isString, toNumber } from './shared' +import { isNumber, isString, toNumber } from './shared' export function getTop(element: HTMLElement): number { const { top } = element.getBoundingClientRect() @@ -136,9 +136,11 @@ interface ScrollToOptions { animation: (progress: number) => number } -export function scrollTo(element: HTMLElement, { top = 0, left = 0, duration = 300, animation }: ScrollToOptions) { +export function scrollTo(element: HTMLElement | Window, { top = 0, left = 0, duration = 300, animation }: ScrollToOptions) { const startTime = Date.now() - const { scrollTop, scrollLeft } = element + + const scrollTop = getScrollTop(element) + const scrollLeft = getScrollLeft(element) const frame = () => { const progress = (Date.now() - startTime) / duration