window
객체의 load
이벤트는 스타일, 이미지 등의 리소스들이 모두 로드되었을 때 실행된다. load
이벤트는 onload
프로퍼티를 통해서도 사용할 수 있다.
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));
};
사용자가 현재 페이지를 떠나 다른 페이지로 이동하려 할 때나 창을 닫으려고 할 때 beforeunload
핸들러에서 추가 확인을 요청할 수 있다.
beforeunload
이벤트를 취소하려 하면 브라우저는 사용자에게 확인을 요청한다.
아래 예시를 실행하고, 브라우저에서 새로 고침을 해 직접 확인해보자.
window.onbeforeunload = function() {
return false;
};
false
말고도 비어있지 않은 문자열을 반환하면 이벤트를 취소한 것과 같은 효과를 볼 수 있는데, 이는 역사적인 이유 때문에 남아있는 기능이다. 과거엔 문자열을 반환하면 브라우저에서 이 문자열을 보여줬었는데, 근래의 명세서에선 이를 권장하지 않는다.
예시를 살펴보자.
window.onbeforeunload = function() {
return "저장되지 않은 변경사항이 있습니다. 정말 페이지를 떠나실 건 가요?";
};
이렇게 문자열을 반환하도록 해도 얼럿창에 문자열이 보이지 않게 된 이유는 몇몇 사이트 관리자들이 오해가 생길 법하거나 성가신 메시지를 띄우면서 beforeunload
를 남용했기 때문입니다. 오래된 브라우저에서 위 예시를 실행하고 새로 고침을 누르면 “저장되지 않은…” 메시지가 뜨긴 합니다. 하지만 모던 브라우저에선 beforeunload
이벤트를 취소할 때 보이는 메시지를 커스터마이징 할 수 없습니다.
문서가 완전히 로드된 후에 DOMContentLoaded
핸들러를 설정하면 어떤 일이 발생할까?
아마도 절대 실행되지 않을 것이다.
그런데 가끔은 문서가 로드되었는지 아닌지를 판단할 수 없는 경우가 있다. DOM이 완전히 구성된 후에 특정 함수를 실행해야 할 때는 DOM 트리 완성 여부를 알 수 없어 조금 난감하다.
이럴 때 현재 로딩 상태를 알려주는 document.readyState
프로퍼티를 사용할 수 있다.
프로퍼티의 값은 세 종류가 있습니다.
"loading"
– 문서를 불러오는 중일 때"interactive"
– 문서가 완전히 불러와졌을 때"complete"
– 문서를 비롯한 이미지 등의 리소스들도 모두 불러와졌을 때우리는 document.readyState
의 값을 확인하고 상황에 맞게 핸들러를 설정하거나 코드를 실행하면 된다.
예시:
function work() { /*...*/ }
if (document.readyState == 'loading') {
// 아직 로딩 중이므로 이벤트를 기다립니다.
document.addEventListener('DOMContentLoaded', work);
} else {
// DOM이 완성되었습니다!
work();
}
document.readyState
는 DOMContentLoaded
가 실행되기 바로 직전에 interactive
가 된다. 따라서 DOMContentLoaded
와 interactive
는 같은 상태를 나타낸다고 볼 수 있다.document.readyState
는 iframe
, img
를 비롯한 리소스 전부가 로드되었을 때 complete
가 된다. 위 예시에서 우리는 readyState
의 값이 img.onload
와 window.onload
가 실행된 시점과 거의 동일한 시점에 complete
로 바뀌었다는 것을 확인할 수 있다. readyState
의 값이 complete
로 바뀐다는 것은 window.onload
가 실행된다는 것과 동일한 의미이다. 이 둘의 차이점은 window.onload
는 다른 load
핸들러가 전부 실행된 후에야 동작한다는 것에 있다.