ABOUT ME

-

  • [ Vite + React ] ContextMenu 우클릭 메뉴 커스텀
    Front/React 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
    반응형