[원티드 프리온보딩] TIL - (4)
5월 6일
마우스 클릭 & 드래그로 스크롤 구현하기
요소들이 상하로 정렬되는 것이 아닌 좌우로 정렬돼있을 시 스크롤이 좌우로 생길 수 있다.
그러한 경우 마우스로는 스크롤하기가 불편한데, 이러한 경우를 위해 마우스 클릭과 드래그로 스크롤을 구현하였다.
const containerRef = useRef();
let position = { left: 0, x: 0 };
const onMouseMove = (e) => {
const x = e.clientX - position.x;
containerRef.current.scrollLeft = position.left - x;
};
const onMouseUp = () => {
containerRef.current.style.cursor = "grab";
document.removeEventListener("mousemove", onMouseMove);
document.removeEventListener("mouseup", onMouseUp);
};
const onMouseDown = (e) => {
position = {
left: containerRef.current.scrollLeft,
x: e.clientX,
};
containerRef.current.style.cursor = "grabbing";
document.addEventListener("mousemove", onMouseMove);
document.addEventListener("mouseup", onMouseUp);
};
return (
<div
ref={containerRef}
role="none"
className={styles.container}
onMouseDown={onMouseDown}
>
<ul>
<li>1</li>
<li>2</li>
<li>3</li>
<li>4</li>
<li>5</li>
</ul>
</div>
);
총 코드는 이러하다.
파헤치기
const containerRef = useRef();
스크롤을 적용할 컨테이너 ref
다.
let position = { left: 0, x: 0 };
컨테이너의 스크롤 위치와 이벤트가 발생한 마우스의 위치를 판별할 객체이다.
const onMouseDown = (e) => {
position = {
left: containerRef.current.scrollLeft,
x: e.clientX,
};
containerRef.current.style.cursor = "grabbing";
document.addEventListener("mousemove", onMouseMove);
document.addEventListener("mouseup", onMouseUp);
};
마우스를 누르는 순간 position
에 대한 값을 설정하고, 마우스를 움직일 때와 뗏을 때의 이벤트 리스너를 추가한다.
const onMouseMove = (e) => {
const x = e.clientX - position.x;
containerRef.current.scrollLeft = position.left - x;
};
마우스의 움직임에 따라 마우스가 눌린 위치로부터 얼마나 이동했는지를 구하고, 그 값으로 컨테이너의 스크롤 위치를 변경시켜준다.
const onMouseUp = () => {
containerRef.current.style.cursor = "grab";
document.removeEventListener("mousemove", onMouseMove);
document.removeEventListener("mouseup", onMouseUp);
};
마우스를 떼는 순간 마우스를 눌렀을 때 추가된 이벤트 리스너를 모두 제거한다.
여담
자바스크립트만을 사용해 구현하였지만 나중에는 라이브러리를 활용해봐도 좋을 것 같다.