Front/React

[ Vite + React ] ContextMenu 우클릭 메뉴 커스텀

Yume Dev 2024. 10. 12. 01:22
반응형

 

기존 크롬 화면에서 우클릭시에는 기본 크롬 메뉴가 나오는데 이를 막고 원하는 메뉴를 설정해서 나오게 구현


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가 좌클릭으로 되어있어서 화면에서 좌클릭을 하지 않으면 커스텀 메뉴가 안닫히는 경우가 생긴다.

728x90
반응형