window.onload, onunload, onbeforeunload, readyState

q6hillz·2022년 4월 17일
1

javascript

목록 보기
49/60
post-custom-banner

window.onload 설명

window 객체의 load 이벤트는 스타일, 이미지 등의 리소스들이 모두 로드되었을 때 실행된다. load 이벤트는 onload 프로퍼티를 통해서도 사용할 수 있다.

window.onunload 설명

window 객체의 unload 이벤트는 사용자가 페이지를 떠날 때, 즉 문서를 완전히 닫을 때 실행된다. unload 이벤트에선 팝업창을 닫는 것과 같은 딜레이가 없는 작업을 수행할 수 있다.

그런데 분석 정보를 보내는 것은 예외사항에 속한다.

사용자가 웹사이트에서 어떤 행동을 하는지에 대한 분석 정보를 모으고 있다고 가정해보자.

unload 이벤트는 사용자가 페이지를 떠날 때 발생하므로 자연스럽게 unload 이벤트에서 분석 정보를 서버로 보내는 게 어떨까 하는 생각이 든다.

메서드 navigator.sendBeacon(url, data)은 바로 이런 용도를 위해 만들어졌다. 메서드에 대한 자세한 설명은 https://w3c.github.io/beacon/에서 찾아볼 수 있다.

sendBeacon는 데이터를 백그라운드에서 전송한다. 다른 페이지로 전환시 분석 정보는 제대로 서버에 전송되지만, 딜레이가 없는 것은 바로 이 때문이다.

sendBeacon은 다음과 같이 사용할 수 있다.

let analyticsData = { /* 분석 정보가 담긴 객체 */ };

window.addEventListener("unload", function() {
  navigator.sendBeacon("/analytics", JSON.stringify(analyticsData));
};
  • 요청은 POST 메서드로 전송된다.
  • 요청 시 문자열뿐만 아니라 폼이나 fetch에서 설명하는 기타 포맷들도 보낼 수 있다. 대개는 문자열 형태의 객체가 전송된다.
  • 전송 데이터는 64kb를 넘을 수 없다.

window.onbeforeunload

사용자가 현재 페이지를 떠나 다른 페이지로 이동하려 할 때나 창을 닫으려고 할 때 beforeunload 핸들러에서 추가 확인을 요청할 수 있다.

beforeunload 이벤트를 취소하려 하면 브라우저는 사용자에게 확인을 요청한다.

아래 예시를 실행하고, 브라우저에서 새로 고침을 해 직접 확인해보자.

window.onbeforeunload = function() {
  return false;
};

false말고도 비어있지 않은 문자열을 반환하면 이벤트를 취소한 것과 같은 효과를 볼 수 있는데, 이는 역사적인 이유 때문에 남아있는 기능이다. 과거엔 문자열을 반환하면 브라우저에서 이 문자열을 보여줬었는데, 근래의 명세서에선 이를 권장하지 않는다.

예시를 살펴보자.

window.onbeforeunload = function() {
  return "저장되지 않은 변경사항이 있습니다. 정말 페이지를 떠나실 건 가요?";
};

이렇게 문자열을 반환하도록 해도 얼럿창에 문자열이 보이지 않게 된 이유는 몇몇 사이트 관리자들이 오해가 생길 법하거나 성가신 메시지를 띄우면서 beforeunload를 남용했기 때문입니다. 오래된 브라우저에서 위 예시를 실행하고 새로 고침을 누르면 “저장되지 않은…” 메시지가 뜨긴 합니다. 하지만 모던 브라우저에선 beforeunload 이벤트를 취소할 때 보이는 메시지를 커스터마이징 할 수 없습니다.

readyState

문서가 완전히 로드된 후에 DOMContentLoaded 핸들러를 설정하면 어떤 일이 발생할까?

아마도 절대 실행되지 않을 것이다.

그런데 가끔은 문서가 로드되었는지 아닌지를 판단할 수 없는 경우가 있다. DOM이 완전히 구성된 후에 특정 함수를 실행해야 할 때는 DOM 트리 완성 여부를 알 수 없어 조금 난감하다.

이럴 때 현재 로딩 상태를 알려주는 document.readyState 프로퍼티를 사용할 수 있다.

프로퍼티의 값은 세 종류가 있습니다.

  • "loading" – 문서를 불러오는 중일 때
  • "interactive" – 문서가 완전히 불러와졌을 때
  • "complete" – 문서를 비롯한 이미지 등의 리소스들도 모두 불러와졌을 때

우리는 document.readyState의 값을 확인하고 상황에 맞게 핸들러를 설정하거나 코드를 실행하면 된다.

예시:

function work() { /*...*/ }

if (document.readyState == 'loading') {
  // 아직 로딩 중이므로 이벤트를 기다립니다.
  document.addEventListener('DOMContentLoaded', work);
} else {
  // DOM이 완성되었습니다!
  work();
}

<실행 순서>

  1. [1] initial readyState:loading
  2. [2] readyState:interactive
  3. [2] DOMContentLoaded
  4. [3] iframe onload
  5. [4] img onload
  6. [4] readyState:complete
  7. [4] window onload
  • document.readyStateDOMContentLoaded가 실행되기 바로 직전에 interactive가 된다. 따라서 DOMContentLoadedinteractive는 같은 상태를 나타낸다고 볼 수 있다.
  • document.readyStateiframe, img를 비롯한 리소스 전부가 로드되었을 때 complete가 된다. 위 예시에서 우리는 readyState의 값이 img.onloadwindow.onload가 실행된 시점과 거의 동일한 시점에 complete로 바뀌었다는 것을 확인할 수 있다. readyState의 값이 complete로 바뀐다는 것은 window.onload가 실행된다는 것과 동일한 의미이다. 이 둘의 차이점은 window.onload는 다른 load 핸들러가 전부 실행된 후에야 동작한다는 것에 있다.
post-custom-banner

0개의 댓글