이전글 : https://challeee.tistory.com/14
[React] 웹에서 가로 터치 스크롤 만들기(1/2)
React 웹 환경에서 세로 스크롤은 스크롤바 말고도 마우스 휠로 화면을 스크롤 할 수 있어서 불편함이 없지만 가로 스크롤의 경우 스크롤바로 스크롤 하는게 편하지는 않습니다. 그래서 모바일
challeee.tistory.com
이전 글에서 모바일 환경처럼 터치 드래그로 스크롤 할 수 있는 기능을 구현하였습니다.
가로 스크롤은 아주 흔하게 사용되는 기능 중 하나이기때문에 우리는 이 기능을 컴포넌트로 만들어서 여러 페이지에서 사용할 수 있게 만들겁니다. 추가로 드래그 시 클릭이벤트가 발생 되는 문제를 해결하겠습니다.
1. HorizontalScroll 컴포넌트 생성
먼저 프로젝트에 컴포넌트들을 관리 할 폴더를 만들고 거기다 가로 스크롤 컴포넌트를 만듭니다.
2. 코드 삽입
만든 js 파일과 css 파일에 코드 들을 옮겨 줍니다. 저는 HorizontalScroll 이라고 명명 하였습니다. 스크롤 안에 보여줄 컨텐츠 리스트들은 children으로 받아올 수 있습니다.
HorizontalScroll.js
import styles from './HorizontalScroll.module.css'
import React, { useEffect, useRef, useState } from 'react'
export default function HorizontalScroll({ children }) {
const scrollRef = useRef(null);;
const [isDrag, setIsDrag] = useState(false);
const [start, setStart] = useState("");
const onMouseDown = (event) => {
event.preventDefault();
setIsDrag(true);
setStart(event.pageX + scrollRef.current.scrollLeft);
};
const onMouseUp = (event) => {
setIsDrag(false);
};
const onDragMove = (event) => {
if (isDrag) {
scrollRef.current.scrollLeft = start - event.pageX;
}
};
return (
<>
<main >
<div>
<div className={styles.list}
onMouseDown={onMouseDown}
onMouseMove={isDrag ? onDragMove : null}
onMouseUp={onMouseUp}
onMouseLeave={onMouseUp}
ref={scrollRef}>
{children}
</div>
</div>
</main>
</>
)
}
HorizontalScroll.module.css
.list {
display: flex;
min-width : 100%;
flex-direction: row;
overflow: hidden;
align-items: center;
overflow-x: auto;
}
.list::-webkit-scrollbar {
display: none;
}
3. 만들어진 컴포넌트를 사용할 페이지에서 컴포넌트를 import 후 사용합니다. 컴포넌트 안에 리스트를 출력해주면 컴포넌트의 children으로 리스트가 전달 됩니다.
import HorizontalScroll from '../components/HorizontalScroll/HorizontalScroll'
...
<HorizontalScroll>
{
list.map((item, index) => (
<div className={styles.item} key={index}
onClick={() => {
isDrag ? null : console.log(`${index}번 클릭입니다`)
}}>
<p>{item}</p>
</div>
))
}
</HorizontalScroll>
...
4. 완료
이렇게 하면 가로스크롤의 컴포넌트 생성 및 사용이 완료 됩니다.
5. 개선 사항
가로 스크롤 자체는 잘 작동되지만 아직 해결해야 할 문제가 있습니다. 드래그 할 때 스크롤 내부 컨텐츠를 드래그 할 텐데 드래그와 함께 클릭 이벤트가 같이 발동 됩니다.
이를 해결 하기 위해 onClick event에 드래그 시작 X좌표와 종료 X좌표를 비교하여 같을때만 발동하도록 조건을 걸어 보겠습니다.
먼저 새로운 변수를 만들고 onMouseDown, on MouseUp 함수에 값을 설정 하도록 하겠습니다. 그리고 onClick 함수를 만들어 시작좌표와 끝 좌표 비교하여 이벤트를 발생시켜보도록 하겠습니다.
...
const [startPageX, setStartPageX] = useState(); //추기
const [endPageX, setEndPageX] = useState(); // 추가
const onMouseDown = (event) => {
event.preventDefault();
setIsDrag(true);
setStart(event.pageX + scrollRef.current.scrollLeft);
setStartPageX(event.pageX) // 추가
};
const onMouseUp = (event) => {
setEndPageX(event.pageX) // 추가
setIsDrag(false);
}
// onClick 이벤트 추가
const onClick = (e) => {
if (startPageX - endPageX !== 0) {
e.preventDefault();
}
};
...
<div className={styles.list}
onMouseDown={onMouseDown}
onMouseMove={isDrag ? onDragMove : null}
onMouseUp={onMouseUp}
onMouseLeave={onMouseUp}
onClick={onClick} // 추가
ref={scrollRef}>
{children}
</div>
코드를 위처럼 수정해 주시면 이제 드래그 할때는 스크롤 내부 컨텐츠에 클릭 이벤트가 발생하지 않습니다.
이걸로 가로 스크롤 기능 개발을 마무리 하도록하겠습니다.
추가 개선사항이 있거나 오류가 있는 부분은 언제든지 지적해주시면 감사하겠습니다.
'React' 카테고리의 다른 글
[React] infinite scroll(무한 스크롤) 구현 - Intersection Observer (0) | 2023.06.07 |
---|---|
[React] infinite scroll(무한 스크롤) 구현 - scroll event (0) | 2023.05.31 |
[React] useMemo 사용법 및 예제, 변수 재사용 - react hook (0) | 2023.05.29 |
[React] 웹에서 가로 터치 스크롤 만들기(1/2) (0) | 2023.05.18 |
React를 해야 하는 이유, 특징 및 장단점 (0) | 2023.04.11 |