Weather Forecast 프로젝트를 만들면서 만났던 이슈에 대해 포스팅해보고자 한다.
📍 문제 발생
Weather Forecast 프로젝트에서 오늘의 날씨를 보여주는 섹션 중 하단에 현재 시간 이후 24시간 동안 날씨와 기온을 나타내 보여주는 섹션이 있다. 이 부분을 보기 위해서 노트북 키패드로 작동 시에는 그냥 옆으로 넘기면서 작동하면 됐지만, 마우스를 이용할 때에는 하단에 스크롤 바를 눌러 움직이는 방식으로 이동해야 했다. 즉 마우스 휠을 했을 때 가로 스크롤이 작동이 되지 않았던 것이었다. 사용자 경험을 바탕으로 사용자가 이용하는데 불편함을 느낄 것이라 생각하여 개선하고자 하였다.
📍 고민 및 해결 과정
처음 접근했던 방식은 시간마다 날씨 및 기온 정보 li들을 감싸는 ul와 li를 css transform을 활용하여 rotate(90)/ rotate(-90)를 통해 ul top 부분을 웹에서 봤을 땐 left면으로 바꿔주었고 원래 right부분이었던 면을 top면으로 보이게 설정하였다. 이에 맞게 li도 방향에 맞게 돌려주었더니 아래와 같이 보였다.

해당 화면에 보이는 것과 같이 transform을 활용하면 또 다른 문제점들이 생겼다.
아무래도 margin 관리나 웹 화면상의 해당 섹션 위치 컨트롤이 어려워진 것이다. 즉 코드 가독성도 떨어지고 위치 조정 및 설계가 번거로워졌다. 특히 반응형 웹 구현을 위해 높이, 넓이를 vw, vh 등과 같은 반응형 단위를 사용하게 되면 도형이 화면상에서 위치가 고정된 상태에서 크기가 조정되는 게 아닌 위치 또한 이동이 있다는 문제점이 나타났다.
따라서 어찌어찌 기능은 구현할 수 있지만 이 방법은 적합하지 않다고 생각하여 다른 접근법을 고민해 보았다.
그러던 중 마우스 휠 이벤트가 있다는 것을 알았고 Wheel 이벤트를 적극 활용하였다.
📍 해결 방법 및 코드
React의 useRef로 DOM 엘리먼트의 ref를 가져와서 이벤트 리스너를 연결하였다.
그리고 Wheel 이벤트에 deltaY 속성이 있는데 이는 세로 스크롤 양을 나타낸다. 따라서 스크롤 방향을 left로 설정하여 x축으로 전환하였고 세로 스크롤한 양을 더해주었다.
useRef로 가져온 DOM 엘리먼트에 마우스 wheel 이벤트에 대한 event listener를 추가하고 필요에 따라 제거하여 성능 이슈를 방지하였다.
[ Code View ]
import { useRef, useEffect } from "react";
export function useHorizontalScroll() {
const elRef = useRef();
useEffect(() => {
const el = elRef.current; //custom hooks로 DOM 엘리먼트의 ref를 가져와서 이벤트 리스너를 연결하고, horizontal scroll 컴포넌트를 구현하였다.
if (el) {
const onWheel = e => {
if (e.deltaY == 0) return;
e.preventDefault();
el.scrollTo({ // scrollTo를 이용하여 특정 위치로 이동 시키기
left: el.scrollLeft + e.deltaY, // 휠 이벤트 작동시 x축으로 이동 + deltaY는 Y축 스크롤량을 반환하는데 그 반환한 만큼 x축으로 이동하도록 하여 좌우 휠 스크롤 작동
behavior: "smooth" // 부드럽게 움직이는 효과
});
};
el.addEventListener("wheel", onWheel); // 걸려있는 이벤트 핸들러 추가
return () => el.removeEventListener("wheel", onWheel); // 마우스 wheel이벤트에 대한 event listener를 추가하고 필요에따라 제거해서 성능 이슈를 방지한다.
}
}, []);
return elRef;
}
[ Wheel 이벤트 작동되는 화면 ]

'Javascript' 카테고리의 다른 글
[Javascript] 배열 고차 함수 reduce()에 대해 (1) | 2024.06.19 |
---|---|
[Javascript] Map 객체 (0) | 2024.04.03 |
[Javascript] 문자열 양쪽 끝 공백 제거하는 trim() (0) | 2024.03.20 |
[비동기 HTTP 통신] Ajax, Axios, Fetch에 대해 (1) | 2024.03.13 |