기본 콘텐츠로 건너뛰기

Pinned Post

배우자 유산·사산휴가 신설부터 출산 전 배우자 출산휴가, 임신 중 배우자를 위한 육아휴직까지 핵심 내용 정리

2026년 9월 18일 시행 2026년 9월 18일부터 달라지는 배우자 지원 3종 세트 배우자 유산·사산휴가 신설부터 출산 전 배우자 출산휴가, 임신 중 배우자를 위한 육아휴직까지 핵심 내용 정리 작성 기준일 : 2026년 9월 18일 고용노동부 보도자료와 국가법령정보센터의 2026년 시행 법령을 기준으로 정리했습니다. 제도 및 급여 기준은 향후 법령·고시·행정지침 등에 따라 변경될 수 있으므로 실제 신청 전 고용노동부 또는 고용24에서 다시 확인하는 것이 좋습니다. 핵심 요약 ① 유산·사산 최대 5일 최초 3일 유급 ② 배우자 출산휴가 20일 출산예정일 50일 전부터 사용 가능 ③ 임신 중 배우자 육아휴직 출산 전 가능 유산·조산 등 위험이 있는 경우 1. 배우자가 유산·사산한 경우 최대 5일 휴가 2026년 9월 18일부터 배우자의 유산 또는 사산을 이유로 근로자가 사용할 수 있는 배우자 유산·사산휴가 가 신설됩니다. 핵심 조건 휴가 기간 : 5일 범위 최초 3일은 유급 배우자가 유산 또는 사산한 날부터 20일 이내 청구 사업주는 해당 휴가를 이유로 해고하거나 불리한 처우를 할 수 없음 「남녀고용평등과 일·가정 양립 지원에 관한 법률」 제18조의4에 이러한 내용이 규정되어 있습니다. 다만 법에서 정한 예외에 해당하는 인공 임신중절에 따른 유산에는 적용되지 않습니다. 우선지원대상기업이라면 급여 지원도 확인 우선지원대상기업 근로자는 유급 대상인 최초 3일에 대해 통상임금 100% 수준의 배우자 유산·사산휴가 급여 지원 대상이 될 수 있습니다. 고용노동부가 ...

JavaScript History API 2편 : pushState()와 popstate를 직접 만들어 보기

JavaScript · Beginner · Part 2

JavaScript History API 2편
pushState()와 popstate를 직접 만들어 보기

페이지를 새로 이동하지 않고 URL을 바꾸고, 브라우저 뒤로가기와 앞으로가기에 따라 화면 상태까지 복원해 봅니다.

작성 기준일 : 2026년 9월 16일

1. 1편에서 무엇을 배웠을까?

1편에서는 아주 간단한 게시글 목록을 만들었습니다.

목록 검색 상세 뒤로가기

그리고 검색어를 URL에 넣었습니다.

list.html?keyword=JavaScript

검색할 때는 replaceState()를 사용했습니다.

history.replaceState(
    null,
    "",
    url
);

이번 2편에서는 여기서 한 단계 더 나아가겠습니다.

2. 이번에는 이런 것을 만들어 봅니다

이번에는 게시글 목록 화면에서 페이지 번호를 클릭한다고 생각해 보겠습니다.

1페이지 2페이지 3페이지

그런데 페이지를 클릭할 때마다 실제 HTML 페이지를 다시 로드하지 않는다고 가정합니다.

화면은 JavaScript가 변경하고 URL만 다음처럼 바꿉니다.

list.html?page=1
list.html?page=2
list.html?page=3
이번 편의 목표

URL이 바뀌었을 때 브라우저의 뒤로가기와 앞으로가기도 정상적으로 동작하게 만들어 봅니다.

3. 먼저 아주 간단한 페이지를 만들어 봅니다

별도의 서버 없이 브라우저에서 실행할 수 있는 간단한 예제입니다.

<!DOCTYPE html>
<html lang="ko">
<head>
    <meta charset="UTF-8">
    <title>History API 실습</title>
</head>

<body>

<h1>게시글 목록</h1>

<div id="page"></div>

<button data-page="1">1페이지</button>
<button data-page="2">2페이지</button>
<button data-page="3">3페이지</button>

<script>

const pageElement =
    document.querySelector("#page");

function renderPage(page) {

    pageElement.textContent =
        `${page}페이지를 보고 있습니다.`;

}

renderPage(1);

</script>

</body>
</html>

버튼을 눌러도 아직 아무 일도 일어나지 않습니다.

이제 버튼을 눌렀을 때 화면을 바꿔보겠습니다.

document
    .querySelectorAll("button")
    .forEach(button => {

        button.addEventListener("click", () => {

            const page =
                button.dataset.page;

            renderPage(page);

        });

    });

이제 버튼을 누르면 화면의 페이지 번호가 변경됩니다.

그런데 주소창은 그대로입니다.

4. 화면과 URL이 서로 따로 움직이고 있습니다

현재 상태를 생각해 봅시다.

화면

3페이지를 보고 있음

URL

여전히 list.html

이 상태에서는 브라우저 입장에서 1페이지에서 2페이지, 2페이지에서 3페이지로 이동했다는 사실을 알 수 없습니다.

따라서 브라우저의 뒤로가기 버튼을 눌러도 우리가 만든 페이지 상태를 되돌릴 방법이 없습니다.

5. pushState()를 사용해 봅니다

이번에는 버튼을 클릭할 때 History에 새로운 항목을 추가하겠습니다.

history.pushState(
    null,
    "",
    "?page=2"
);

페이지를 새로 이동하지 않았는데 주소가 다음처럼 변경됩니다.

list.html?page=2

여기서 중요한 것은 새로운 History entry가 추가된다는 점입니다.

list.html list.html?page=2

이제 브라우저 입장에서도 새로운 History 상태가 생겼습니다.

6. pushState()를 버튼에 연결합니다

이제 실제 버튼에 적용해 보겠습니다.

document
    .querySelectorAll("button")
    .forEach(button => {

        button.addEventListener("click", () => {

            const page =
                button.dataset.page;

            const url =
                `?page=${page}`;

            history.pushState(
                null,
                "",
                url
            );

            renderPage(page);

        });

    });

이제 다음과 같은 흐름이 만들어집니다.

1페이지 클릭
↓
URL ?page=1
↓
2페이지 클릭
↓
URL ?page=2
↓
3페이지 클릭
↓
URL ?page=3

중요한 점은 페이지 전체가 새로 로드되지 않는다는 것입니다.

7. 그런데 뒤로가기를 눌러보면?

여기서 많은 주니어 개발자가 처음 헷갈립니다.

pushState()로 History를 만들었지만, 뒤로가기를 눌렀다고 해서 자동으로 화면이 2페이지로 변경되는 것은 아닙니다.

브라우저의 URL은 변경되지만 JavaScript가 화면을 다시 그려야 합니다.

여기서 등장하는 것이 popstate입니다.

8. popstate란?

브라우저의 History 이동으로 현재 문서의 History entry가 변경될 때 JavaScript에서 이를 처리할 수 있도록 사용하는 이벤트가 popstate입니다.

아주 간단하게 이벤트를 먼저 만들어 보겠습니다.

window.addEventListener(
    "popstate",
    () => {

        console.log("History가 변경되었습니다.");

    }
);

이제 브라우저의 뒤로가기나 앞으로가기로 History를 이동하면 이벤트에서 그 변화를 처리할 수 있습니다.

9. URL에서 page를 읽습니다

URL이 다음과 같다고 생각해 봅시다.

list.html?page=2

1편에서 배웠던 URLSearchParams를 그대로 사용할 수 있습니다.

function getPageFromUrl() {

    const params =
        new URLSearchParams(
            window.location.search
        );

    return Number(
        params.get("page") || 1
    );

}

이제 URL이 현재 어떤 페이지를 가리키고 있는지 JavaScript가 알 수 있습니다.

10. popstate에서 화면을 다시 그립니다

이제 핵심 코드를 작성합니다.

window.addEventListener(
    "popstate",
    () => {

        const page =
            getPageFromUrl();

        renderPage(page);

    }
);

이제 흐름은 다음과 같습니다.

브라우저 뒤로가기

History 변경

popstate 발생

URL에서 page 읽기

화면 다시 그리기

11. 전체 코드를 합쳐봅니다

이제 지금까지 작성한 코드를 하나의 HTML 파일로 합쳐보겠습니다.

<!DOCTYPE html>
<html lang="ko">

<head>
    <meta charset="UTF-8">
    <title>History API 실습</title>
</head>

<body>

<h1>게시글 목록</h1>

<div id="page"></div>

<button data-page="1">1페이지</button>
<button data-page="2">2페이지</button>
<button data-page="3">3페이지</button>


<script>

const pageElement =
    document.querySelector("#page");


function renderPage(page) {

    pageElement.textContent =
        `${page}페이지를 보고 있습니다.`;

}


function getPageFromUrl() {

    const params =
        new URLSearchParams(
            window.location.search
        );

    return Number(
        params.get("page") || 1
    );

}


document
    .querySelectorAll("button")
    .forEach(button => {

        button.addEventListener(
            "click",
            () => {

                const page =
                    button.dataset.page;

                history.pushState(
                    null,
                    "",
                    `?page=${page}`
                );

                renderPage(page);

            }
        );

    });


window.addEventListener(
    "popstate",
    () => {

        const page =
            getPageFromUrl();

        renderPage(page);

    }
);


renderPage(
    getPageFromUrl()
);

</script>

</body>

</html>

12. 직접 테스트해 봅니다

이제 브라우저에서 실제로 테스트해 보세요.

HTML 파일을 실행합니다.

1페이지 → 2페이지 → 3페이지를 클릭합니다.

주소창의 URL이 변경되는지 확인합니다.

브라우저 뒤로가기를 누릅니다.

2페이지로 화면이 변경되는지 확인합니다.

다시 뒤로가기를 눌러 1페이지로 이동합니다.

앞으로가기로 2페이지, 3페이지도 이동해 봅니다.

13. pushState()와 replaceState()의 차이

이제 1편에서 사용했던 replaceState()와 비교해 보겠습니다.

구분 pushState() replaceState()
History 새로운 entry 추가 현재 entry 변경
뒤로가기 이전 entry로 이동 가능 별도의 entry를 추가하지 않음
사용 예 페이지·화면 상태 이동 현재 URL 상태 갱신
pushState()

A → B → C

History를 하나 더 만듭니다.

replaceState()

A → B → C'

현재 History entry를 바꿉니다.

14. 주니어 개발자가 꼭 기억할 것

pushState()는 URL만 바꾸는 함수라고 생각하면 부족합니다.

브라우저 History에 새로운 상태를 추가하고, 그 상태에 맞게 화면을 변경하는 것은 개발자가 처리해야 합니다.

그래서 pushState() + popstate + 화면 렌더링을 함께 이해해야 합니다.

15. 실무에서는 이렇게 연결됩니다

지금 만든 예제는 실제 서비스에서 훨씬 복잡한 형태로 발전할 수 있습니다.

실습 실무
page 페이지 번호
keyword 검색어
URLSearchParams 검색·필터·정렬 조건
pushState() 화면 상태를 History에 추가
popstate 뒤로가기·앞으로가기 상태 처리
renderPage() 실제 화면 렌더링

16. 1편과 2편을 연결해서 이해하기

1편
검색어를 URL에 저장

URLSearchParams

replaceState()

2편
화면 상태를 History에 추가

pushState()

popstate

화면 상태 복원

이렇게 연결해서 이해하면 History API가 단순히 "주소창의 URL을 바꾸는 기능"이 아니라는 것을 알 수 있습니다.

17. 다음 단계에서는 무엇을 할까?

여기까지 이해했다면 다음 단계에서는 검색과 페이지 이동을 하나로 묶어볼 수 있습니다.

list.html
    ↓
검색
    ↓
list.html?keyword=JavaScript
    ↓
페이지 2
    ↓
list.html?keyword=JavaScript&page=2
    ↓
상세 페이지
    ↓
뒤로가기
    ↓
검색어 + 페이지 상태 복원

그리고 이 구조가 조금 더 발전하면 Vue Router나 React Router 같은 SPA 라우팅 구조를 이해하는 데 필요한 기본 개념으로 연결됩니다.

18. 실습 체크리스트

□ 1페이지, 2페이지, 3페이지 버튼을 만들었다.

□ 버튼 클릭으로 화면을 변경했다.

□ pushState()로 URL을 변경했다.

□ URLSearchParams로 page를 읽었다.

□ popstate 이벤트를 등록했다.

□ 브라우저 뒤로가기를 테스트했다.

□ 브라우저 앞으로가기도 테스트했다.

□ pushState()와 replaceState()의 차이를 이해했다.

19. FAQ

pushState()를 호출하면 페이지가 새로고침되나요?

일반적인 페이지 이동처럼 현재 문서를 새로 로드하지 않고 History entry를 추가하면서 URL을 변경할 수 있습니다.

pushState()를 호출하면 화면도 자동으로 변경되나요?

아닙니다. URL과 History 상태를 변경한 뒤 실제 화면을 어떻게 변경할지는 JavaScript 코드에서 처리해야 합니다.

뒤로가기를 누르면 왜 popstate가 필요한가요?

History 이동에 따라 URL이 변경되었을 때 그 상태를 읽고 화면을 다시 렌더링하기 위해 사용할 수 있습니다.

모든 URL 변경에 pushState()를 사용하면 되나요?

그렇지는 않습니다. 새로운 History 단계로 남겨야 하는 상태인지, 현재 History entry만 변경하면 되는 상태인지에 따라 선택해야 합니다.

20. 마무리

2편에서는 복잡한 프레임워크 없이 순수 HTML과 JavaScript만으로 브라우저 History의 동작을 직접 확인했습니다.

pushState()
새로운 History 상태 추가

popstate
History 이동 감지

URLSearchParams
현재 상태 확인

render()
화면 복원

결국 중요한 것은 함수 이름을 외우는 것이 아닙니다.

"URL 상태와 화면 상태를 어떻게 연결하고, 브라우저 History 이동에 따라 화면을 어떻게 복원할 것인가?"

이 개념을 이해하면 이후 SPA 라우팅을 공부할 때도 단순히 라이브러리 사용법을 외우는 것이 아니라 그 내부에서 어떤 일이 일어나는지 이해할 수 있습니다.

참고 자료

  • MDN Web Docs — History API
  • MDN Web Docs — history.pushState()
  • MDN Web Docs — history.replaceState()
  • MDN Web Docs — popstate event
  • MDN Web Docs — URLSearchParams
업데이트 안내

Web API의 세부 동작은 브라우저 및 웹 표준의 변경에 따라 달라질 수 있습니다. 실제 프로젝트에 적용하기 전 사용하는 브라우저의 최신 공식 문서를 확인하는 것을 권장합니다.

#JavaScript #HistoryAPI #pushState #replaceState #popstate #URLSearchParams #HTML #WebDevelopment #주니어개발자

댓글

이 블로그의 인기 게시물

ChatGpt 의 유료결제 영수증 및 청구서 다운로드

ChatGpt 의 유료결제 영수증 및 청구서 다운로드   https://chatgpt.com/  사이트에 접속하며 회원가입을 합니다.   ChatGpt 유료 결제를 위해서는 왼쪽 하단에 있는 " Team 워크스페이스 추가 "를 선택합니다.   https://chatgpt.com/     ChatGPT의 요금제는 세 가지로 나뉩니다:  Free ,  Plus , 그리고  Custom Plan (기업용 요금제). 각 요금제의 특징과 차이점은 다음과 같습니다. 1.  Free Plan (무료 플랜) 사용 모델:  GPT-3.5 제공 기능:  기본적인 질문 응답, 텍스트 생성 접속 가능성:  트래픽이 많을 때는 사용이 제한될 수 있으며, 응답 속도가 느릴 수 있습니다. 제한 사항:  최신 모델이나 고급 기능을 사용할 수 없고, 성능이나 속도 면에서 제한이 있습니다. 2.  Plus Plan (플러스 플랜) 월 요금:  $20 사용 모델:  GPT-4 장점:  더 빠른 응답 속도, 트래픽이 많을 때도 안정적인 접속 가능 차이점:  GPT-4의 향상된 성능으로 더 복잡한 질문이나 고급 작업에도 우수한 결과를 제공합니다. 접속 가능성:  트래픽이 많아도 안정적이며, 더 나은 응답 속도를 제공합니다. 3.  Custom Plan (맞춤형 플랜) 대상:  대규모 기업 또는 특정 요구사항이 있는 고객 요금:  고객의 요구에 따라 맞춤 설정 특징:  기업 맞춤형 기능과 성능을 제공하며, 보안, 데이터 정책, API 액세스와 같은 맞춤형 옵션을 포함할 수 있습니다. 차이점:  대규모 기업에 특화된 기능으로, 추가 지원과 고급 기능 제공이 가능합니다. 주요 차이점 모델 사용:  Free는 GPT-3.5,...

인천국제공항 제1여객터미널에서 일본으로 가는 출국 절차 안내 ✈️

인천공항 제1여객터미널 출국 절차 가이드 (탑승동 이동 및 셔틀트레인 완벽 정리) 공항 도착부터 체크인, 보안검색, 출국심사, 그리고 셔틀트레인을 타고 탑승동으로 이동하는 전체 출국 단계를 빠짐없이 안내합니다. 1. 공항 도착 시간 항공기 출발 3시간 전 제1여객터미널 3층 출국장 도착 권장 2. 탑승구 확인 101~132번 게이트는 셔틀트레인을 타고 탑승동 으로 이동 필수 3. 되돌아오기 불가 셔틀트레인은 편도 이동만 가능하므로 본동 면세품 인도 후 탑승 Step 1. 공항 도착 및 체크인 (3층 일반지역) 항공기 출발 3시간 전 공항 3층 출국장에 도착하는 것을 권장합니다. 셀프 체크인 & 자동 수하물 위탁(Self Bag-Drop): 키오스크에서 모바일·지류 탑승권을 발급받고 전용 카운터를 이용하면 대기시간을 크게 단축할 수 있습니다. 유인 카운터: 여권과 항공권(e-티켓)을 제시하여 좌석 배정 및 위탁 수하물을 처리합니다. Step 2. 출국 전 사전 준비 (환전 및 통신) 환전 수령: 사전 신청한 외화를 3층 또는 지하 1층 환전소·은행 영업점에서 수령합니다. 로밍 및 통신: 통신사 부스에서 데이터 로밍 확인 또는 신청한 USIM/eSIM/와이파이 단말기를 수령합니다. 기타 편의시설: 외투 보관 서비스, 약국, 여행자 보험 창구 이용은 보안검색장 진입 전 일반지역에서 마쳐야 합니다. Step 3. 출국장 진입 및 보안 검색 3층 출국장 게이트(2~5번)로 이동하여 탑승권과 여권을 확인받고 보안검색대로 이동합니다. 주의 (액체류 규정 안내) 기내 반입 액체류는 개별 용기당 100ml 이하, 1인당 총 1L 투명...

엑셀·워드와 호환되는 최신 WYSIWYG 웹 에디터 강추

최신 자료를 기반으로 엑셀과 워드 호환이 잘 되는 상위 10개의 WYSIWYG 웹에디터를 조사하겠습니다. 이 목록은 사용량, 기능, 개발자 선호도를 고려하여 선정되며, 각 웹에디터의 공식 웹사이트 링크도 함께 제공해드리겠습니다.  엑셀·워드와 호환되는 최신 WYSIWYG 웹 에디터 10선 1.  CKEditor 5 오픈 소스 기반의  CKEditor 5 는 높은 완성도의 WYSIWYG 웹 에디터로, Drupal 등 주요 CMS에서 기본 에디터로採용될 정도로 널리 쓰입니다 ( Drupal and CKEditor: a history of advanced content editing | CKEditor | CKEditor ). 풍부한 플러그인과 커스터마이징 기능을 제공하며,  Microsoft Word  문서를 댓글이나 변경 추적 내용까지 포함하여 불러오는 고급 호환 기능도 갖추고 있습니다 ( Wysiwyg Editors Statistics 2025 ). 또한 별도 플러그인을 통해 편집한 내용을 바로  .docx  워드 파일로 내보낼 수 있어 워드 호환성이 뛰어납니다 ( Export to Word | CKEditor 5 Documentation ). 개발자들은 CKEditor 5의 모듈식 설계와 활발한 커뮤니티 지원을 선호하며, 기업용 협업 편집 기능 등의 프리미엄 옵션도 제공됩니다. 2.  TinyMCE TinyMCE 는 오랜 역사와 함께 가장 널리 사용되는 웹 에디터 중 하나로, WordPress에서는 수년간 기본 편집기로採用되어 왔습니다. Joomla, Umbraco, Shopify 등 수많은 CMS에 내장되어 있으며, 전 세계 웹 콘텐츠의 약 40%가 TinyMCE로 작성·출판되고 있다고 합니다 ( Configure TinyMCE for your CMS to rival Wix and WordPress | TinyMCE ). 기본 기능만으로도 강력하지만,...