DOMContentLoaded, load, beforeunload, unload 이벤트

lee jae hwan·2022년 8월 14일

브라우저

목록 보기
35/39

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>

0개의 댓글