event page ๊ด๋ จ ๐
์ ์ก๊ฐ์ event page๋ฅผ ๊ตฌํํ๊ณ ์ ํ๋ค. ๋ง์ฐ์ค๋ฅผ 'press'ํ๊ณ (click๊ณผ ๊ตฌ๋ถํ ๊ฒ) ์ฐ์ธก์์ ์ข์ธก์ผ๋ก ๋๊ธฐ๋ฉด, ์งํ์ค์ธ event๋ค์ด oveflow๋๋ ๋ชจ์ต์ ๋ณผ ์ ์๋ค. best practice๋ฅผ ์ดํดํ๋ ๋ฐฉ์์ ํํ๋ค.
best practice ๐ต
import React, { useState } from "react";
import styled from "styled-components";
const CardContainer = styled.div`
display: flex;
overflow-x: scroll;
width: 100%;
height: 200px;
background-color: #f0f0f0;
cursor: grab;
`;
const Card = styled.div`
flex: 0 0 200px;
height: 100%;
background-color: #fff;
border: 1px solid #ccc;
margin-right: 10px;
display: flex;
justify-content: center;
align-items: center;
font-size: 20px;
`;
const App = () => {
const [isMousePressed, setIsMousePressed] = useState(false);
const [containerScrollLeft, setContainerScrollLeft] = useState(0);
const [startMouseX, setStartMouseX] = useState(0);
const handleMousePress = (e) => {
setIsMousePressed(true);
setStartMouseX(e.pageX - e.currentTarget.offsetLeft);
setContainerScrollLeft(e.currentTarget.scrollLeft);
};
const handleMouseMove = (e) => {
if (!isMousePressed) return;
e.preventDefault();
const currentMouseX = e.pageX - e.currentTarget.offsetLeft;
const mouseMovement = currentMouseX - startMouseX;
console.log(mouseMovement);
console.log("2", containerScrollLeft);
e.currentTarget.scrollLeft = containerScrollLeft - mouseMovement;
};
const handleMouseRelease = () => {
setIsMousePressed(false);
};
return (
<CardContainer
// ๋๋ฅด๋ ์๊ฐ
onMouseDown={handleMousePress}
onMouseMove={handleMouseMove}
onMouseUp={handleMouseRelease}
onMouseLeave={handleMouseRelease}
>
{/* ์นด๋ ์ปดํฌ๋ํธ๋ค */}
<Card>Card 1</Card>
<Card>Card 2</Card>
<Card>Card 3</Card>
<Card>Card 4</Card>
<Card>Card 5</Card>
<Card>Card 1</Card>
<Card>Card 2</Card>
<Card>Card 3</Card>
<Card>Card 4</Card>
<Card>Card 5</Card>
</CardContainer>
);
};
export default App;
card container์ onMouseDown, onMouseMove, onMouseUp, onMouseLeave๊ฐ ์กด์ฌํ๋ค.
onClick์ 'ํด๋ฆญ'ํ ๋ ํน์ event ๊ฐ์ฒด๊ฐ ๋ฐ์ํ๋ค. ์ ์์๋ค๋ ๋ง์ฐฌ๊ฐ์ง์ด๋ค.
onMouseDown๋ ๋ง์ฐ์ค๋ก pressํ ๋, onMouseMove๋ ๋ง์ฐ์ค๋ก ๋์์ ์์ง์ผ ๋, onMouseUp๋ ๋ง์ฐ์ค๋ฅผ ๋ ๋, onMouseLeave๋ ํน์ element์์ ๋ง์ฐ์ค๊ฐ ๋ ๋ฌ์ ๋ event ๊ฐ์ฒด๋ฅผ ๋ฐ์์ํจ๋ค.
onMouseDown์๋ handleMousePress ํจ์๊ฐ ์ ๋ฌ๋๋ค. isMousePressed๋ผ๋ ์ํ๋ฅผ true๋ก ๋ณ๊ฒฝํ๋ค. ์ด์ด์ startMouseX๋ผ๋ ์ํ๋ฅผ, 'press'ํ๋ ์๊ฐ page์ x์ขํ์์ card container์ offsetLeft๋ฅผ ๋บ ๊ฐ์ผ๋ก updateํ๋ค. ๋ง์ง๋ง์ผ๋ก containerScrollLeft๋ผ๋ ์ํ๋ฅผ e.currentTarget.scrollLeft๋ก updateํ๋ค
pressํ ์ํ๋ผ๋ฉด if๋ฌธ์ ํต๊ณผํ ๋ค preventDefault ํจ์๊ฐ ์คํ๋๋ค. ์ดํ currentMouseX ์์์ page์ x์ขํ์์ offsetLeft๋ฅผ ๋บ ๊ฐ์ ํ ๋นํ๋ค. ์์ง์ธ ์ดํ์ x์ขํ๋ฅผ ์๋ฏธํ๊ธฐ์ startMouseX์ x์ขํ์๋ ๊ตฌ๋ถ๋๋ค๋ ์ ์ ์ธ์งํด์ผ ํ๋ค.
mouseMovement ์์๋ currrent page์ x์ขํ์์ start page์ x์ขํ๋ฅผ ๋บ ๊ฐ์ด ํ ๋น๋๋ค.
preventDefault, currentMouseX ํ ๋น, mouseMovement ํ ๋น์ด ์ข ๋ฃ๋๋ฉด, ๋ง์ง๋ง์ผ๋ก e.currentTarget.scrollLeft ๊ฐ์ containerScrollLeft์์ mouseMovement๋ฅผ ๋บ ๊ฐ์ผ๋ก ๋ณํํ๋ค.
isMousePressed๋ฅผ false๋ก ๋ณํํ๋ ๊ธฐ๋ฅ๋ง์ ์ํํ๋ ํจ์์ด๋ค.
ํ๊ณ ๐ด
containerScrollLeft ๋ถ๋ถ์ด ์ดํด๊ฐ ๋์ง ์์๋ค. ๋ด์ผ์ containerScrollLeft๊น์ง ๋ช ํํ๊ฒ ์ดํดํด์ ํ๋ก์ ํธ์ ์ ์ฉํ๋ ๋ฐ ์ฑ๊ณตํ๊ธธ ๋ฐ๋๋ค. ์ดํดํ์ง ๋ชปํ๊ณ ์๋ ค๋๊น ๊ต์ฅํ ์ฐ์ฐํ๋ฐ, ์ฒ์ ์๋ํด ๋ณด๋ ๊ฑฐ๋๊น ์ฒซ ์ ์ ๋ฐฐ๋ถ๋ฅด๋ ค ์์ฌ๋ด์ง ๋ง์. ๋ฐ๋ณด ๊ฐ์ ์ฃผ์ ์ ํ ํ์ ์ดํด๋๊ธธ ๋ฐ๋ผ๋ ๊ฑด '์ค๋ฒ'๋ค.