feat: update back-top
parent
2394d9f844
commit
20d11c891e
|
@ -1,5 +1,5 @@
|
||||||
module.exports = {
|
module.exports = {
|
||||||
dev: {
|
dev: {
|
||||||
componentName: 'avatar', // dev components
|
componentName: 'back-top', // dev components
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
|
|
|
@ -1,5 +1,6 @@
|
||||||
import { mount } from '@vue/test-utils';
|
import { mount } from '@vue/test-utils';
|
||||||
import BackTop from '..';
|
import BackTop from '..';
|
||||||
|
import { sleep } from '../../../tests/utils';
|
||||||
|
|
||||||
describe('BackTop', () => {
|
describe('BackTop', () => {
|
||||||
it('should scroll to top after click it', async () => {
|
it('should scroll to top after click it', async () => {
|
||||||
|
@ -8,12 +9,39 @@ describe('BackTop', () => {
|
||||||
visibilityHeight: -1,
|
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
|
// trigger scroll manually
|
||||||
wrapper.vm.handleScroll();
|
wrapper.vm.handleScroll();
|
||||||
await new Promise(resolve => setTimeout(resolve, 0));
|
await sleep();
|
||||||
wrapper.find('.ant-back-top').trigger('click');
|
wrapper.find('.ant-back-top').trigger('click');
|
||||||
await new Promise(resolve => setTimeout(resolve, 1000));
|
await sleep(500);
|
||||||
expect(Math.abs(Math.round(document.documentElement.scrollTop))).toBe(0);
|
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();
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
|
@ -4,13 +4,13 @@
|
||||||
>
|
>
|
||||||
> If you decide to use custom styles, please note the size limit: no more than `40px * 40px`.
|
> If you decide to use custom styles, please note the size limit: no more than `40px * 40px`.
|
||||||
|
|
||||||
| Property | Description | Type | Default |
|
| Property | Description | Type | Default | Version |
|
||||||
| --- | --- | --- | --- |
|
| --- | --- | --- | --- | --- |
|
||||||
| target | specifies the scrollable area dom node | () => HTMLElement | () => window |
|
| 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 |
|
| visibilityHeight | the `BackTop` button will not show until the scroll height reaches this value | number | 400 | |
|
||||||
|
|
||||||
### events
|
### events
|
||||||
|
|
||||||
| Events Name | Description | Arguments |
|
| Events Name | Description | Arguments | Version |
|
||||||
| ----------- | -------------------------------------------------------------------- | --------- |
|
| --- | --- | --- | --- |
|
||||||
| click | a callback function, which can be executed when you click the button | Function |
|
| click | a callback function, which can be executed when you click the button | Function | |
|
||||||
|
|
|
@ -1,4 +1,3 @@
|
||||||
import raf from 'raf';
|
|
||||||
import PropTypes from '../_util/vue-types';
|
import PropTypes from '../_util/vue-types';
|
||||||
import addEventListener from '../vc-util/Dom/addEventListener';
|
import addEventListener from '../vc-util/Dom/addEventListener';
|
||||||
import getScroll from '../_util/getScroll';
|
import getScroll from '../_util/getScroll';
|
||||||
|
@ -7,16 +6,7 @@ import getTransitionProps from '../_util/getTransitionProps';
|
||||||
import { ConfigConsumerProps } from '../config-provider';
|
import { ConfigConsumerProps } from '../config-provider';
|
||||||
import Base from '../base';
|
import Base from '../base';
|
||||||
import { getListeners } from '../_util/props-util';
|
import { getListeners } from '../_util/props-util';
|
||||||
|
import scrollTo from '../_util/scrollTo';
|
||||||
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;
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
function getDefaultTarget() {
|
function getDefaultTarget() {
|
||||||
return window;
|
return window;
|
||||||
|
@ -70,33 +60,13 @@ const BackTop = {
|
||||||
},
|
},
|
||||||
|
|
||||||
scrollToTop(e) {
|
scrollToTop(e) {
|
||||||
const scrollTop = this.getCurrentScrollTop();
|
const { target = getDefaultTarget } = this;
|
||||||
const startTime = Date.now();
|
scrollTo(0, {
|
||||||
const frameFunc = () => {
|
getContainer: target,
|
||||||
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);
|
|
||||||
this.$emit('click', e);
|
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() {
|
handleScroll() {
|
||||||
const { visibilityHeight, target = getDefaultTarget } = this;
|
const { visibilityHeight, target = getDefaultTarget } = this;
|
||||||
const scrollTop = getScroll(target(), true);
|
const scrollTop = getScroll(target(), true);
|
||||||
|
|
|
@ -4,13 +4,13 @@
|
||||||
>
|
>
|
||||||
> 自定义样式宽高不大于 40px \* 40px。
|
> 自定义样式宽高不大于 40px \* 40px。
|
||||||
|
|
||||||
| 参数 | 说明 | 类型 | 默认值 |
|
| 参数 | 说明 | 类型 | 默认值 | 版本 |
|
||||||
| --- | --- | --- | --- |
|
| --- | --- | --- | --- | --- |
|
||||||
| target | 设置需要监听其滚动事件的元素,值为一个返回对应 DOM 元素的函数 | Function | () => window |
|
| target | 设置需要监听其滚动事件的元素,值为一个返回对应 DOM 元素的函数 | Function | () => window | |
|
||||||
| visibilityHeight | 滚动高度达到此参数值才出现 `BackTop` | number | 400 |
|
| visibilityHeight | 滚动高度达到此参数值才出现 `BackTop` | number | 400 | |
|
||||||
|
|
||||||
### 事件
|
### 事件
|
||||||
|
|
||||||
| 事件名称 | 说明 | 回调参数 |
|
| 事件名称 | 说明 | 回调参数 | 版本 |
|
||||||
| -------- | ------------------ | -------- |
|
| -------- | ------------------ | -------- | ---- |
|
||||||
| click | 点击按钮的回调函数 | Function |
|
| click | 点击按钮的回调函数 | Function | |
|
||||||
|
|
Loading…
Reference in New Issue