diff --git a/build/config.js b/build/config.js index daa63f67e..452a79999 100644 --- a/build/config.js +++ b/build/config.js @@ -1,5 +1,5 @@ module.exports = { dev: { - componentName: 'avatar', // dev components + componentName: 'back-top', // dev components }, }; diff --git a/components/back-top/__tests__/index.test.js b/components/back-top/__tests__/index.test.js index eb685240e..806d32bf0 100644 --- a/components/back-top/__tests__/index.test.js +++ b/components/back-top/__tests__/index.test.js @@ -1,5 +1,6 @@ import { mount } from '@vue/test-utils'; import BackTop from '..'; +import { sleep } from '../../../tests/utils'; describe('BackTop', () => { it('should scroll to top after click it', async () => { @@ -8,12 +9,39 @@ describe('BackTop', () => { visibilityHeight: -1, }, }); - document.documentElement.scrollTop = 400; + const scrollToSpy = jest.spyOn(window, 'scrollTo').mockImplementation((x, y) => { + window.scrollY = y; + window.pageYOffset = y; + }); + window.scrollTo(0, 400); // trigger scroll manually wrapper.vm.handleScroll(); - await new Promise(resolve => setTimeout(resolve, 0)); + await sleep(); wrapper.find('.ant-back-top').trigger('click'); - await new Promise(resolve => setTimeout(resolve, 1000)); - expect(Math.abs(Math.round(document.documentElement.scrollTop))).toBe(0); + await sleep(500); + expect(window.pageYOffset).toBe(0); + scrollToSpy.mockRestore(); + }); + it('support onClick', async () => { + const onClick = jest.fn(); + const wrapper = mount(BackTop, { + propsData: { + visibilityHeight: -1, + }, + listeners: { + click: onClick, + }, + }); + const scrollToSpy = jest.spyOn(window, 'scrollTo').mockImplementation((x, y) => { + window.scrollY = y; + window.pageYOffset = y; + }); + window.scrollTo(0, 400); + // trigger scroll manually + wrapper.vm.handleScroll(); + await sleep(); + wrapper.find('.ant-back-top').trigger('click'); + expect(onClick).toHaveBeenCalled(); + scrollToSpy.mockRestore(); }); }); diff --git a/components/back-top/index.en-US.md b/components/back-top/index.en-US.md index dac518a63..166e7481d 100644 --- a/components/back-top/index.en-US.md +++ b/components/back-top/index.en-US.md @@ -4,13 +4,13 @@ > > If you decide to use custom styles, please note the size limit: no more than `40px * 40px`. -| Property | Description | Type | Default | -| --- | --- | --- | --- | -| target | specifies the scrollable area dom node | () => HTMLElement | () => window | -| visibilityHeight | the `BackTop` button will not show until the scroll height reaches this value | number | 400 | +| Property | Description | Type | Default | Version | +| --- | --- | --- | --- | --- | +| target | specifies the scrollable area dom node | () => HTMLElement | () => window | | +| visibilityHeight | the `BackTop` button will not show until the scroll height reaches this value | number | 400 | | ### events -| Events Name | Description | Arguments | -| ----------- | -------------------------------------------------------------------- | --------- | -| click | a callback function, which can be executed when you click the button | Function | +| Events Name | Description | Arguments | Version | +| --- | --- | --- | --- | +| click | a callback function, which can be executed when you click the button | Function | | diff --git a/components/back-top/index.jsx b/components/back-top/index.jsx index cea79fa4c..4a4df1bfc 100644 --- a/components/back-top/index.jsx +++ b/components/back-top/index.jsx @@ -1,4 +1,3 @@ -import raf from 'raf'; import PropTypes from '../_util/vue-types'; import addEventListener from '../vc-util/Dom/addEventListener'; import getScroll from '../_util/getScroll'; @@ -7,16 +6,7 @@ import getTransitionProps from '../_util/getTransitionProps'; import { ConfigConsumerProps } from '../config-provider'; import Base from '../base'; import { getListeners } from '../_util/props-util'; - -const easeInOutCubic = (t, b, c, d) => { - const cc = c - b; - t /= d / 2; - if (t < 1) { - return (cc / 2) * t * t * t + b; - } else { - return (cc / 2) * ((t -= 2) * t * t + 2) + b; - } -}; +import scrollTo from '../_util/scrollTo'; function getDefaultTarget() { return window; @@ -70,33 +60,13 @@ const BackTop = { }, scrollToTop(e) { - const scrollTop = this.getCurrentScrollTop(); - const startTime = Date.now(); - const frameFunc = () => { - const timestamp = Date.now(); - const time = timestamp - startTime; - this.setScrollTop(easeInOutCubic(time, scrollTop, 0, 450)); - if (time < 450) { - raf(frameFunc); - } else { - this.setScrollTop(0); - } - }; - raf(frameFunc); + const { target = getDefaultTarget } = this; + scrollTo(0, { + getContainer: target, + }); this.$emit('click', e); }, - setScrollTop(value) { - const getTarget = this.target || getDefaultTarget; - const targetNode = getTarget(); - if (targetNode === window) { - document.body.scrollTop = value; - document.documentElement.scrollTop = value; - } else { - targetNode.scrollTop = value; - } - }, - handleScroll() { const { visibilityHeight, target = getDefaultTarget } = this; const scrollTop = getScroll(target(), true); diff --git a/components/back-top/index.zh-CN.md b/components/back-top/index.zh-CN.md index f75d14623..87c97b9ff 100644 --- a/components/back-top/index.zh-CN.md +++ b/components/back-top/index.zh-CN.md @@ -4,13 +4,13 @@ > > 自定义样式宽高不大于 40px \* 40px。 -| 参数 | 说明 | 类型 | 默认值 | -| --- | --- | --- | --- | -| target | 设置需要监听其滚动事件的元素,值为一个返回对应 DOM 元素的函数 | Function | () => window | -| visibilityHeight | 滚动高度达到此参数值才出现 `BackTop` | number | 400 | +| 参数 | 说明 | 类型 | 默认值 | 版本 | +| --- | --- | --- | --- | --- | +| target | 设置需要监听其滚动事件的元素,值为一个返回对应 DOM 元素的函数 | Function | () => window | | +| visibilityHeight | 滚动高度达到此参数值才出现 `BackTop` | number | 400 | | ### 事件 -| 事件名称 | 说明 | 回调参数 | -| -------- | ------------------ | -------- | -| click | 点击按钮的回调函数 | Function | +| 事件名称 | 说明 | 回调参数 | 版本 | +| -------- | ------------------ | -------- | ---- | +| click | 点击按钮的回调函数 | Function | |