본문으로 건너뛰기
안형우

안녕하세요. 14년차 풀스택 웹개발자 안형우입니다. 이 블로그에서는 WordPress, PHP, CSS, 사용성, 리눅스 서버 등 풀스택 웹개발에서 마주하는 다양한 문제 상황과 해결책, 필요한 개념들을 다룹니다. 👉 소개


작업물

📌 CSS가 어려운 이유 — 프로젝트 중심 실전 CSS 강의 소개 2023-04-13
📌 워드프레스, 답답한 빌더와 플러그인 대신 시원하게 커스터마징하기(강의) 2023-01-15
📌 아무도 말하지 않는 PHP의 좋은 점 2018-10-13
📌 유지보수하기 쉬운 CSS 전략(슬라이드) 2016-12-20
📌 워드프레스 테마에서 템플릿 파일 매칭 순서 2013-05-12
📌 [번역] CSS 코드 냄새 2013-01-01

모달 레이어 팝업 등에서 URL을 변경해 뒤로 가기 버튼을 작동하게 하기 – pushState, popstate 활용 규칙 메모

black and gray compass on top of map
Photo by Alexander Andrews on Unsplash

미리보기를 띄우면 URL에 ?preview가 붙으면서 미리보기가 뜨고, 미리보기를 닫으면 URL에 있는 ?preview가 사라지면서 닫히는 식의 기능을 만들 때 참고하려고 정리한 메모입니다. pushState()popstate를 사용합니다.

이렇게 URL을 달리하면 prev, next 버튼에 따라서 미리보기가 닫히고 열립니다.

그리고 해당 URL로 직접 접근했을 때도 미리 보기를 열거나 닫을 수 있습니다.

메모

history.pushState()는 URL을 바꾸고 History의 단계는 추가하지만 window에 popstate 이벤트는 발생시키지 않습니다.

popstate 이벤트는 뒤로 가기 버튼이나 앞으로 가기 버튼을 클릭하는 경우, 혹은 JS에서 history.back()이나 history.forward()를 호출한 경우에만 발생합니다.

따라서 URL에 따른 페이지 요소의 상태 변화는 다음과 같이 작성해야 합니다.

  1. open, close 메서드를 작성(또는 start, end 메서드).
  2. 클릭 이벤트에서 history.pushState() 실행하고 open, close 메서드(또는 start, end 메서드) 실행.
  3. toggleByUrl 작성. URL에 따라 open, close 메서드(또는 start, end 메서드) 실행하는 메서드.
  4. popstate 이벤트 핸들러로 toggleByUrl 메서드 바인딩.
  5. URL로 직접 들어왔을 때 toggleByUrl 메서드 바인딩.

예시

아래는 지금 제 블로그에서 사용하는 print.js 파일과 관련 CSS 내용입니다.

이 글의 제목 아래쪽 프린트 버튼을 눌러 보시면 어떤 효과인지 확인하실 수 있습니다.

if (document.querySelector('.js-start-print-mode')) {

    const start = () => {
        window.scrollTo(0, 0);
        document.body.classList.add('print');
    }

    const end = () => {
        document.body.classList.remove('print');
    }

    const addSearchParamOnUrl = () => {
        history.pushState({isPrintMode: true}, '', '?print-mode');
    }
    const removeSearchParamOnUrl = () => {
        let url = new URL(location);
        url.searchParams.delete('print-mode');
        history.pushState({isPrintMode: false}, '', url);
    }

    const toggleByUrl = () => {
        let url = new URL(location);

        if (url.searchParams.has('print-mode')) {
            start();
        }

        if (!url.searchParams.has('print-mode')) {
            end();
        }
    }

    document.querySelector('.js-start-print-mode').addEventListener('click', e => {
        addSearchParamOnUrl();
        start();
    });

    document.querySelector('.js-end-print-mode').addEventListener('click', e => {
        removeSearchParamOnUrl();
        end();
    });

    window.addEventListener('popstate', toggleByUrl);

    toggleByUrl();
}
.no-print-but-show-on-print-mode-display {
    display: none
}

.print .no-print-but-show-on-print-mode-display {
    display: block;
    text-align: center
}

@media print {
    .print .no-print-but-show-on-print-mode-display {
        display: none
    }

    .print h1, .print h2, .print h3, .print h4, .print h5, .print h6 {
        -moz-column-break-after: avoid;
        break-after: avoid
    }
}

안녕하세요. 14년차 풀스택 웹개발자 안형우입니다. 이 블로그에서는 WordPress, PHP, CSS, 사용성, 리눅스 서버 등 풀스택 웹개발에서 마주하는 다양한 문제 상황과 해결책, 필요한 개념들을 다룹니다. 👉 소개


작업물

Leave a Reply

Your email address will not be published. Required fields are marked *