이전에 react-indiana-drag-scroll 라이브러리를 사용하여 구현한 마우스 드래그 스크롤 기능에는 치명적인 문제가 있었다..
바로 input 태그가 동작하지 않는다는 문제였는 데 이와 관련해서 메일도 보내 보았지만 답장을 받지 못해서 반쯤 포기하고 있다가 라이브러리 없이 js를 이용하여 마우스 드래그 스크롤을 구현한 블로그를 발견했다.
아직 코드를 이해하는 중이라 자세한 설명은 여기를 보는 게 좋을 것 같다.
아래 코드는 위 블로그 코드를 기반으로 해서 약간의 변형과 결과물이다!
/components/layout/WidthScroll.js 파일을 만들어서 아래 코드를 삽입 해줬다.
여기에서 원본 코드 + 약간의 변형이 들어갔다.
1) document
기존 코드에서는 JS 버전이라서 document를 아래와 같이 사용하시는 데
const slider = document.querySelector('.items');
React나 Next.js에서는 이렇게 쓰면 오류가 발생한다. (해결 방법은 아래 참고)
2) pointer
기능 자체가 마우스 클릭으로 드래그를 하는 건데 클릭을 해도 시각적으로 변화가 없길래 아래와 같이 CSS 추가 해주고
.pointer {
cursor: pointer;
}
addEventListener 콜백 함수 안에 삭제/추가 해줬다.
- mousedown, mouseleave, mouseup > slider.classList.remove("pointer");
- mousemove > slider.classList.add("pointer");
👉 전체 코드
const WidthScroll = ({ children }) => {
let slider = "";
if (typeof document !== "undefined") {
slider = document.querySelector(".items");
}
let isDown = false;
let startX;
let scrollLeft;
if (slider) {
slider.addEventListener("mousedown", (e) => {
isDown = true;
slider.classList.add("active");
startX = e.pageX - slider.offsetLeft;
scrollLeft = slider.scrollLeft;
// 나머지 경우에는 마우스 포인터 삭제
slider.classList.remove("pointer");
});
slider.addEventListener("mouseleave", () => {
isDown = false;
slider.classList.remove("active");
// 나머지 경우에는 마우스 포인터 삭제
slider.classList.remove("pointer");
});
slider.addEventListener("mouseup", () => {
isDown = false;
slider.classList.remove("active");
// 나머지 경우에는 마우스 포인터 삭제
slider.classList.remove("pointer");
});
slider.addEventListener("mousemove", (e) => {
if (!isDown) return;
e.preventDefault();
const x = e.pageX - slider.offsetLeft;
const walk = x - startX;
slider.scrollLeft = scrollLeft - walk;
// 마우스를 눌러서 드래그 스크롤 할 때만 cursor pointer 설정
slider.classList.add("pointer");
});
}
return <div>{children}</div>;
};
export default WidthScroll;
/pages/test2.js 파일을 만들어서 테스트 해줬다.
👉 전체 코드
import WidthScroll from "@/components/layout/WidthScroll";
const Test2 = () => {
return (
<WidthScroll>
<div className="items">
<div class="item item1">01</div>
<div class="item item2">02</div>
<div class="item item3">03</div>
<div class="item item4">04</div>
<div class="item item5">05</div>
<div class="item item6">06</div>
<div class="item item7">07</div>
<div class="item item8">08</div>
<div class="item item9">09</div>
<div class="item item10">10</div>
<div class="item item11">11</div>
<div class="item item12">12</div>
<div class="item item13">13</div>
<div class="item item14">14</div>
<div class="item item15">15</div>
<div class="item item16">16</div>
<div class="item item17">17</div>
<div class="item item18">18</div>
<div class="item item19">19</div>
<div class="item item20">20</div>
<div class="item item21">21</div>
<div class="item item22">22</div>
<div class="item item23">23</div>
<div class="item item24">24</div>
<div class="item item25">25</div>
</div>
</WidthScroll>
);
};
export default Test2;
약간의 CSS
👉 전체 코드
.items {
display: flex;
width: 500px;
overflow: scroll;
}
.items .item {
width: 200px;
height: 500px;
border: 1px solid tomato;
}
결과
'더 알아보기 > 기능' 카테고리의 다른 글
[React] 서명패드 만들기 (0) | 2022.07.22 |
---|---|
[React] 마우스 드래그로 스크롤 구현하기 - 라이브러리 문제점 해결 (0) | 2022.07.18 |
[React] 다중 체크박스 구현하기 (0) | 2022.07.07 |
[Next.js] 수평 dnd 만들기 (2) | 2022.07.04 |
[React] 마우스로 드래그 스크롤 구현하기 - 라이브러리 O (0) | 2022.07.04 |
댓글