html 문서 로드와 이벤트

2024. 5. 12. 18:54개인노트-개인공부

# html 문서 로드와 이벤트

## 주요 이벤트

HTML 문서의 생명주기에는 3가지의 주요 이벤트가 있습니다.

  • DOMContentLoade
  • load
  • beforeunload / unload

## 각각의 이벤트 설명

DOMContentLoaded : 브라우저가 HTML을 전부 읽고 DOM 트리를 완성하는 즉시 발생합니다. 이미지 파일(<img>)이나 스타일시트 등의 기타 자원은 기다리지 않습니다.

load : HTML로 DOM 트리를 만드는 게 완성되었을 뿐만 아니라 이미지, 스타일시트 같은 외부 자원도 모두 불러오는 것이 끝났을 때 발생합니다.

beforeunload / unload : 사용자가 페이지를 떠날 때 발생합니다.

## 각각의 이벤트 활용

DOMContentLoaded : DOM이 준비된 것을 확인한 후 원하는 DOM 노드를 찾아 핸들러를 등록해 인터페이스를 초기화할 때
load : 이미지 사이즈를 확인할 때 등. 외부 자원이 로드된 후이기 때문에 스타일이 적용된 상태이므로 화면에 뿌려지는 요소의 실제 크기를 확인할 수 있음
beforeunload : 사용자가 사이트를 떠나려 할 때, 변경되지 않은 사항들을 저장했는지 확인시켜줄 때
unload : 사용자가 진짜 떠나기 전에 사용자 분석 정보를 담은 통계자료를 전송하고자 할 때

 

## DOMContentLoaded

  • DOMContentLoaded 핸들러는 문서가 로드되었을 때 실행됩니다.
  • 따라서 핸들러 아래쪽에 위치한 <img>뿐만 아니라 모든 요소에 접근할 수 있지만,
  • 이미지가 로드되는 것은 기다리지 않습니다.
  • DOMContentLoaded 이벤트는 document 객체에서 발생합니다.
  • 그래서 DOMContentLoaded 는 반드시 document 에 붙여져야 합니다.
  • 즉, 'DOM 트리가 완성되면 DOMContentLoaded 이벤트가 발생한다' 고 생각하면 됩니다.
<script>
  function ready() {
    alert('DOM이 준비되었습니다!');

    // 이미지가 로드되지 않은 상태이기 때문에 사이즈는 0x0입니다.
    alert(`이미지 사이즈: ${img.offsetWidth}x${img.offsetHeight}`);
  }

  document.addEventListener("DOMContentLoaded", ready);
</script>

<img id="img" src="https://en.js.cx/clipart/train.gif?speed=1&cache=0">

 

### DOMContentLoaded와 scripts

  • 'DOM 트리가 완성되면 DOMContentLoaded 이벤트가 발생한다' 에는 HTML 문서 처리 도중에 만나는 중에 만나는 script 태그의 처리도 포함되어 있습니다.
  • 즉, 모든 script가 실행되고 난 후에 DOMContentLoaded 이벤트가 발생합니다.
  • 예외
    • async 속성이 있는 스크립트
    • document.createElement('script')로 동적으로 생성된 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>

<!-- 실행된 순서 -->
<!-- 1. script src 불러오기 -->
<!-- 2. script alert 출력 -->
<!-- 3. DOMContentLoaded 이벤트 실행("DOM이 준비되었습니다!") -->

 

### DOMContentLoaded와 styles

  • 외부 스타일시트는 DOM에 영향을 주지 않기 때문에 DOMContentLoaded는 외부 스타일시트의 로드가 완료 되기를 기다리지 않습니다.
  • 하지만 브라우저에서는 스타일 시트를 불러오는 태그 바로 다음에 스크립트가 있다면 해당 스크립트는 스타일시트의 로드가 완료될 때까지 실행을 기다리게됩니다.
  • DOMContentLoaded는 모든 script가 실행되어야 합니다. 그래서 예외적으로 위 같은 상황에서는 script를 실행하기 위해서 스타일시트의 로드를 기다리게 됩니다.
<link type="text/css" rel="stylesheet" href="style.css">
<script>
  // 이 스크립트는 위 스타일시트가 로드될 때까지 실행되지 않습니다.
  alert(getComputedStyle(document.body).marginTop);
</script>

 

## window.onload

  • 이 load 이벤트는 스타일(외부 css 포함), 이미지 등의 리소스들이 모두 로드되었을 때(전체 페이지가 로드되었을 때) 실행됩니다.
    • window.addEventListener('load',function() {})
  • load 이벤트는 onload 프로퍼티를 통해서도 사용할 수 있습니다.
    • window.onload = function() {}
  • load 이벤트는 window 객체에 있으므로 반드시 window 객체에 사용해야 합니다.
<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

  • window 객체의 unload 이벤트는 사용자가 페이지를 떠날 때 또는 문서를 완전히 닫을 때 실행됩니다.
  • unload 이벤트에선 팝업창을 닫는 것과 같은 딜레이가 없는 작업을 수행할 수 있습니다.
  • 하지만 분석 정보를 보내는 것은 예외적으로 수행할 수 있습니다. (.sendBeacon())
let analyticsData = { /* 분석 정보가 담긴 객체 */ };

window.addEventListener("unload", function() {
  navigator.sendBeacon("/analytics", JSON.stringify(analyticsData));
};

 

## window.onbeforeunload

  • 사용자가 현재 페이지를 떠나 다른 페이지로 이동하려 할 때나 창을 닫으려고 할 때 beforeunload 핸들러에서 추가 확인을 요청할 수 있습니다.
  • beforeunload 이벤트를 취소하려 하면 브라우저는 사용자에게 확인을 요청합니다.
window.onbeforeunload = function() {
  return false;
};

위 코드를 적용하고 새로고침 버튼을 눌렀을 때 나오는 브라우저 확인창

 

## 정리

  • DOMContentLoaded
    • DOM 구성이 완료되었을 때 document 객체에서 실행됩니다.
    • 요소를 조작하거나 이벤트를 추가하려면 이 이벤트가 실행된 후부터 할 수 있습니다.
  • load
    • 페이지를 비롯한 이미지 등의 자원 전부가 모두 불러와졌을 때 window 객체에서 실행됩니다.
    • 모든 자원이 로드되는 걸 기다리기에는 시간이 오래 걸릴 수 있으므로 이 이벤트는 잘 사용되지 않습니다.
  • beforeunload
    • 사용자가 페이지를 떠나려 할 때 window 객체에서 발생합니다.
  • unload
    • 사용자가 최종적으로 사이트를 떠날 때 window 객체에서 발생합니다.
    • unload 이벤트 핸들러에선 지연을 유발하는 복잡한 작업이나 사용자와의 상호작용은 할 수 없습니다.
    • 하지만 예외적으로 navigator.sendBeacon을 사용해 네트워크 요청을 보낼 수 있습니다.

 

 

참고

https://ko.javascript.info/onload-ondomcontentloaded

https://jake-seo-dev.tistory.com/195

 

'개인노트-개인공부' 카테고리의 다른 글

캐노니컬 태그 (Canonical tag) 란  (1) 2024.06.11
form 사용 유용한 팁  (1) 2024.05.28
JavaScript - 함수 (복습)  (1) 2024.03.10
Javascript - this  (1) 2024.02.04
Node vs Element  (2) 2024.01.28