[ Vite + React ] ContextMenu 우클릭 메뉴 커스텀
기존 크롬 화면에서 우클릭시에는 기본 크롬 메뉴가 나오는데 이를 막고 원하는 메뉴를 설정해서 나오게 구현
ContextMenu Component
해당 메뉴 기능들을 내가 원하는 구역에만 나오게 처리하고 싶어서 컴포넌트를 생성
context_container영역은 props로 전달되어 화면에 나오는 영역이므로 이 영역에서만 우클릭을 할 때 커스텀 메뉴가 나오게 해당 div에 onContextMenu 이벤트를 추가
context_menu는 커스텀한 메뉴바 내용
return (
<>
<div className="context_container" onContextMenu={handleContextMenu}>
{children}
</div>
<div id="context_menu" className={`${isDarkMode ? 'isDarkMode' : ''}`}>
<div className={`context_menu_list ${isDarkMode ? 'dark' : ''}`}>
<div>추가</div>
<div>편집</div>
</div>
</div>
</>
);
display: none 과 postion: absolute를 설정해줘야 클릭한 위치에 메뉴가 나오게 할 수 있다.
#context_menu {
width: 150px;
display: none;
position: absolute;
box-sizing: border-box;
background-color: #F5F7F8;
border-radius: 5px;
padding: 6px;
}
onContextMenu는 우클릭을 클릭시 발생하는 이벤트로 우클릭을 클릭시 해당 함수가 실행
기존 크롬의 메뉴는 나오지 않도록 preventDefault()를 설정하여 이벤트를 막음
이후 context_menu id값을 가져와서 display: none에서 block으로 변경
메뉴 위치는 우클릭을 했을때의 X 좌표와 Y좌표를 통해 클릭한 위치에 메뉴가 나오도록 설정
이후 메뉴가 열려있으면 다른 영역을 클릭했을때 메뉴가 닫히도록 EventListener를 추가
handleClearcontextMenu는 메뉴가 열려있을 때 아무데나 클릭하면 사라지도록 처리
이후 이벤트 중복 발생을 고려하여 다시 EventListner에서 해당 click 이벤트를 제거
const handleClearContextMenu = () => {
const ctxMenu = document.getElementById('context_menu');
ctxMenu.style.display = 'none';
window.removeEventListener('click', handleClearContextMenu);
};
const handleContextMenu = (event: React.MouseEvent<HTMLDivElement>) => {
event.preventDefault();
const ctxMenu = document.getElementById('context_menu');
if (!ctxMenu) return;
ctxMenu.style.display = 'block';
ctxMenu.style.top = `${event.pageY}px`;
ctxMenu.style.left = `${event.pageX}px`;
window.addEventListener('click', handleClearContextMenu, { once: true });
};
Home
home component에서 ContextMenuComponent로 감싸주어서 home 영역에서만 우클릭시 커스텀 메뉴가 나오도록 설정
const HomeMain = () => {
return(
<ContextMenuComponent>
<div className="home-container">
홈
</div>
</ContextMenuComponent>
)
}
이렇게 하면 홈 구역에서만 우클릭을 누르면 커스텀 메뉴가 나오고 영역 밖에서 우클릭하면 크롬 메뉴가 나오게 된다.
click eventListener가 좌클릭으로 되어있어서 화면에서 좌클릭을 하지 않으면 커스텀 메뉴가 안닫히는 경우가 생긴다.