728x90
반응형
useState와 이벤트 리스너를 활용한 커서 기반 사이즈 조절 기능 구현함
import { useEffect, useState } from 'react';
import './App.css';
import LeftContent from './components/LeftContent';
import RightContent from './components/RightContent';
import './index.css';
import { checkPrimeSync } from 'crypto';
import { AnySoaRecord } from 'dns';
function App() {
const [width, setWidth] = useState(200);
const [isDragging, setIsDragging] = useState(false);
const handleMouseDown = () => {
setIsDragging(true);
document.body.style.cursor = 'col-resize';
};
const handleMouseMove = (e: any) => {
if (!isDragging) return;
e.preventDefault();
e.stopPropagation();
const xNumber = e.clientX;
setWidth(xNumber);
};
const handleMouseUp = () => {
setIsDragging(false);
document.body.style.cursor = 'default';
document.removeEventListener('mousemove', handleMouseMove);
document.removeEventListener('mouseup', handleMouseUp);
};
useEffect(() => {
if (isDragging) {
document.addEventListener('mousemove', handleMouseMove);
document.addEventListener('mouseup', handleMouseUp);
} else {
document.removeEventListener('mousemove', handleMouseMove);
document.removeEventListener('mouseup', handleMouseUp);
}
return () => {
document.removeEventListener('mouseup', handleMouseUp);
document.removeEventListener('mousemove', handleMouseMove);
};
}, [isDragging]);
return (
<div className="flex ">
<div className="flex " style={{ width: `${width}px` }}>
<LeftContent />
<div
className="bg-red-400 w-[3px] px-[10px] hover:cursor-col-resize"
onMouseDown={handleMouseDown}
></div>
</div>
<div className="flex-1">
<RightContent />
</div>
</div>
);
}
export default App;
1) 마우스가 div 밖으로 나가도 크기 조절 가능
* mousemove & mouseup 이벤트 : 전역(document)에 등록
* mousedown : div에서 발생
2) mouseup인데도 계속 드래그 됨
* mouseup 이벤트는 드래그가 끝날때마다 제거해야함
* 동시에 mousemove & mouseup 이벤트리스너도 제거
3) 커서 모양이 변경됨 && 움직일때마다 깜빡거림
* 자바스크립트로 동적 커서 모양 변경
const handleMouseDown = () => {
setIsDragging(true);
document.body.style.cursor = 'col-resize';
};
const handleMouseUp = () => {
setIsDragging(false);
document.body.style.cursor = 'default';
document.removeEventListener('mousemove', handleMouseMove);
document.removeEventListener('mouseup', handleMouseUp);
};
3-1) after 가상요소 사용하기
return (
<div className="flex ">
<div className="flex " style={{ width: `${width}px` }}>
<LeftContent />
<div
className="relative
bg-red-400 w-[3px] hover:cursor-col-resize
after:absolute after:top-0 after:right-[-3px] after:w-[10px] after:h-full after:cursor-col-resize "
onMouseDown={handleMouseDown}
></div>
</div>
<div className="flex-1">
<RightContent />
</div>
</div>
);
반응형
'React' 카테고리의 다른 글
페이지네이션 (0) | 2024.08.12 |
---|---|
리액트 폴더구조 : 재귀적으로 컴포넌트 구조 (0) | 2024.07.28 |
리액트 : Redux-toolkit 다크모드 (with. Tailwindcss) (0) | 2024.03.24 |
리액트 : 반응형 사이드 바 (햄버거 메뉴 🍔 ) (0) | 2024.01.02 |
React : 리액트 쿼리 LifeCycle (+ isLoading, isFetching) (0) | 2023.12.21 |