미리보기를 띄우면 URL에 ?preview
가 붙으면서 미리보기가 뜨고, 미리보기를 닫으면 URL에 있는 ?preview
가 사라지면서 닫히는 식의 기능을 만들 때 참고하려고 정리한 메모입니다. pushState()
와 popstate
를 사용합니다.
이렇게 URL을 달리하면 prev, next 버튼에 따라서 미리보기가 닫히고 열립니다.
그리고 해당 URL로 직접 접근했을 때도 미리 보기를 열거나 닫을 수 있습니다.
메모
history.pushState()
는 URL을 바꾸고 History의 단계는 추가하지만 window에 popstate
이벤트는 발생시키지 않습니다.
popstate
이벤트는 뒤로 가기 버튼이나 앞으로 가기 버튼을 클릭하는 경우, 혹은 JS에서 history.back()
이나 history.forward()
를 호출한 경우에만 발생합니다.
따라서 URL에 따른 페이지 요소의 상태 변화는 다음과 같이 작성해야 합니다.
open
,close
메서드를 작성(또는start
,end
메서드).- 클릭 이벤트에서
history.pushState()
실행하고open
,close
메서드(또는start
,end
메서드) 실행. toggleByUrl
작성. URL에 따라open
,close
메서드(또는start
,end
메서드) 실행하는 메서드.popstate
이벤트 핸들러로toggleByUrl
메서드 바인딩.- 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
}
}
댓글 남기기