DOMContentLoaded이벤트
브라우저가 HTML을 전부 읽고 DOM트리 구성을 완료했을때 발생하며 이미지파일이나 스타일시트등의 자원은 기다리지 않는다.
DOM노드에 핸들러를 할당할때 사용
document요소노드에 on프로퍼티로 사용할 수 없다.
load이벤트
DOM트리 구성완료 뿐만 아니라 이미지, 스타일시트등 외부자원도 모두 불러오는 것이 끝났을 때 발생한다.
이미지크기 확인할 때 등 외부 자원이 로드된 후이기 때문에 스타일이 적용된 상태이므로 화면에 랜더링된 요소노드의 실제 크기를 확인할 수 있음
beforeunload/unload
사용자가 페이지를 떠날 때 발생한다.
beforeunload – 사용자가 사이트를 떠나려 할 때, 변경되지 않은 사항들을 저장했는지 확인시켜줄 때
unload – 사용자가 진짜 떠나기 전에 사용자 분석정보를 담은 통계자료를 전송하고자 할 때
브라우저는 HTML을 파싱할때 < script >태그를 만나면, DOM구성을 멈추고 < script >를 실행한다.
스크립트실행이 끝나고 나머지 HTML문서를 파싱한다.
< script >에서 DOM조작 관련 로직을 담고 있을 수 있기 때문에 이런 방지책이 만들어 졌다.
따라서 DOMContentLoaded이벤트 역시 < script > 안에 있는 스크립트가 처리되고 난 후에 발생한다.
<script>
document.addEventListener("DOMContentLoaded", () => {
alert("DOM이 준비되었습니다!");
});
</script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/lodash.js/4.3.0/lodash.js"></script>
<script>
alert("라이브러리 로딩이 끝나고 인라인 스크립트가 실행되었습니다.");
</script>
alert(.....)와 같은 DOM구성과 관련없는 스크립트가 본문에 있으면 DOMContentLoaded이벤트만 지연시킬뿐이다.
script src는 동기식 로딩된후 이후내용이 파싱된다.
DOMContentLoaded를 막지 않는 스크립트
html파싱시 만나는 script태그는 DOM로딩을 멈추고 script태그를 실행한다고 했는데 아래 2가지 예외가 있다.
async속성이 있는 스크립트는 DOMContentLoaded를 멈추게 하지 않는다.
document.createElement('script') 동적생성후 웹페이지에 추가된 스크립트는 DOMContentLoaded를 멈추게 하지 않는다.
DOMContentLoaded와 styles
일반적으로 styles은 head에 적용하기때문에 DOMContentLoaded이벤트와 관련이 없고 load이벤트와 관련이 있다.
그런데 HTML 본문에
< link rel="stylesheet" href="test.css" >
< script > .... < /script >
위와 같이 사용하면 css는 동기적으로 로딩되어 < script >는 외부 스타일시트가 로드된후에 실행되도록 되어있다.
getComputedStyle(document.body).marginTop와같이 외부CSS가 적용된 결과를 스크립트로 사용할 수 있기 때문이다.
이렇게 되면 DOMContentLoaded는 script가 로딩된후 발생되는데 위 경우는 외부CSS도 로딩된후 발생되는 조건이 되는 것이다.
그러나 이런경우가 되려면 본문에 사용해야한다는 조건이 있다.
특정 내용의 외부CSS를 만들어서 본문에 사용하고 그결과를 스크립트가 사용해야하는 경우라면 필요하겠다.
window.onload
script>
window.onload = function() { // window.addEventListener('load', (event) => {와 동일합니다.
alert('페이지 전체가 로드되었습니다.');
// 이번엔 이미지가 제대로 불러와 진 후에 얼럿창이 실행됩니다.
alert(`이미지 사이즈: ${img.offsetWidth}x${img.offsetHeight}`);
};
</script>
<img id="img" src="https://en.js.cx/clipart/train.gif?speed=1&cache=0">
window.onunload
let analyticsData = { /* 분석 정보가 담긴 객체 */ };
window.addEventListener("unload", function() {
navigator.sendBeacon("/analytics", JSON.stringify(analyticsData));
};
window.onbeforeunload
window.onbeforeunload = function() {
return "저장되지 않은 변경사항이 있습니다. 정말 페이지를 떠나실 건 가요?";
};
readyState
현재 문서 로딩상태를 알려주는 document.readyState 프로퍼티를 사용할 수 있다.
"loading" – 문서를 불러오는 중일 때
"interactive" – 문서가 완전히 불러와졌을 때
"complete" – 문서를 비롯한 이미지 등의 리소스들도 모두 불러와졌을 때
function work() { /*...*/ }
if (document.readyState == 'loading') {
// 아직 로딩 중이므로 이벤트를 기다립니다.
document.addEventListener('DOMContentLoaded', work);
} else {
// DOM이 완성되었습니다!
work();
}
<script>
log('초기 readyState:' + document.readyState);
document.addEventListener('readystatechange', () => log('readyState:' + document.readyState));
document.addEventListener('DOMContentLoaded', () => log('DOMContentLoaded'));
window.onload = () => log('window onload');
</script>
<iframe src="iframe.html" onload="log('iframe onload')"></iframe>
<img src="http://en.js.cx/clipart/train.gif" id="img">
<script>
img.onload = () => log('img onload');
</script>