BackTop 컴포넌트 만들기
2019.04.25(7달 전)
블로그 개발 중 스크롤이 되었을 때, 상위로 이동시키는 BackTop
을 적용하기 위해 Ant.Design의 BackTop 컴포넌트를 사용하려고 했다.
하지만 Ant.Design의 BackTop 컴포넌트를 적용해보니 잘 안된다. 따라서 직접 BackTop
컴포넌트를 구현하기로 결정했다.
Ant.Design 홈페이지에선 잘 동작한다.
구현 코드는 다음과 같다.
BackTop.tsx
import React, { Component } from 'react';
import { Icon, Button } from 'antd';
import throttle from 'lodash/throttle';
interface IProps {
scrollStep?: number;
delayMs: number;
target: string;
}
class BackTop extends Component<IProps> {
private content: Element;
private timeoutId: NodeJS.Timeout;
private intervalId: NodeJS.Timeout;
static defaultProps = {
scrollStep: 50,
delayMs: 16,
}
componentDidMount() {
const { target } = this.props;
if (target) {
this.content = document.querySelector(target);
this.content.addEventListener('scroll', this.onScroll);
}
}
onScroll = throttle((e) => {
if (e.target.scrollTop >= 64) {
const backtop = document.querySelector('.backtop');
if (backtop) {
content.classList.add('visible');
}
if (this.timeoutId) {
clearTimeout(this.timeoutId);
}
this.timeoutId = setTimeout(() => {
if (backtop) {
backtop.classList.remove('visible');
}
}, 1500);
} else {
const backtop = document.querySelector('.backtop');
if (backtop) {
backtop.classList.remove('visible');
}
}
}, 200);
scrollStep = () => {
if (this.content.scrollTop === 0) {
clearInterval(this.intervalId);
}
this.content.scrollTo(0, this.content.scrollTop - this.props.scrollStep);
}
scrollToTop = () => {
if (this.content && this.props.target) {
this.intervalId = setInterval(() => {
this.scrollStep();
}, this.props.delayMs);
}
}
render() {
return (
<Button className="backtop" type="primary" shape="circle" onClick={this.scrollToTop}>
<Icon type="to-top" style={{ fontSize: '1.25rem' }} />
</Button>
);
}
}
export default BackTop;
backtop.less
.backtop {
width: 40px;
height: 40px;
position: fixed;
bottom: 16px;
right: 16px;
transition: all 0.25s ease-in;
transform: translateY(10px);
opacity: 0;
&.visible {
opacity: 1;
transform: translateY(0);
}
}
BackTop이 적용된 화면이다.
react
component
backtop
Sung Gyun Oh
Hello world!