[JS] JavaScript 로드 문제해결

    반응형

    Script 로드 오류

    html은 위에서 아래로 순차적으로 파싱을 하는데,

    아래와 같이 스크립트 코드가 상단에 위치할 경우

    html이 완전히 파싱되기 전 스크립트가 실행되어 dom 요소를 잘 가져오지 못한다.

    예를 들어, 버튼이 그려지기 전 상태에서 버튼 이벤트를 발생시키면 오류가 나는데 이러한 현상을 해결하기 위해 세 가지 방법이 있다.

    <!DOCTYPE html>
    <html lang="en">
      <head>
        <script>
          let btn = document.querySelector("#btn");
          btn.addEventListener("click", function () {
            alert("button click");
          });
        </script>
      </head>
      <body>
        <button id="btn">버튼</button>
      </body>
    </html>

    01) script 위치 변경

    • <script> 태그를 <body> 태그의 최하단에 배치하여, html이 모두 파싱된 후 dom에 접근
    <!DOCTYPE html>
    <html lang="en">
      <head></head>
      <body>
        <button id="btn">버튼</button>
        <script>
          let btn = document.querySelector("#btn");
          btn.addEventListener("click", function () {
            alert("button click");
          });
        </script>
      </body>
    </html>

    02) load 이벤트 리스너 사용

    • window.onload : html 파싱 → dom 생성 → 외부 콘텐츠(images, script, css 등) 로드된 후 발생하는 이벤트
      <!DOCTYPE html>
      <html lang="en">
        <head>
          <script>
          window.onload = function () {
            let btn = document.querySelector("#btn");
            btn.addEventListener("click", function () {
              alert("button click");
            });
          };
          </script>
        </head>
        <body>
          <button id="btn">버튼</button>
        </body>
      </html>
    • DOMContentLoaded : html 파싱 → dom 생성 후 발생하는 이벤트
      <!DOCTYPE html>
      <html lang="en">
        <head>
         <script>
          document.addEventListener("DOMContentLoaded", function () {
            let btn = document.querySelector("#btn");
            btn.addEventListener("click", function () {
              alert("button click");
            });
          });
         </script>
        </head>
        <body>
          <button id="btn">버튼</button>
        </body>
      </html>

    03) 비동기로 script 로드

    원래는 html 파싱 중간에 스크립트를 로드하면 파싱이 중단되지만,

    defer와 async 속성을 사용하면 html 파싱과 script 로딩을 비동기로 처리함

    또한, defer와 async는 외부 스크립트에만 적용되는 속성으로, <script> 태그 내부에 있는 내용은 영향을 받지 않음

    • defer : html 파싱 후 Javascript 코드 실행  
      <!DOCTYPE html>
      <html lang="en">
        <head>
          <script src="script.js" defer></script>
        </head>
        <body>
          <button id="btn">버튼</button>
        </body>
      </html>
    • async : html 파싱이 완료되지 않았더라도 먼저 로딩되는 Javascript 파일부터 실행하며, Javascript 파일을 실행할 땐 html 파싱이 중단됨
      <!DOCTYPE html>
      <html lang="en">
        <head>
          <script src="script.js" async></script>
        </head>
        <body>
          <button id="btn">버튼</button>
        </body>
      </html>

    반응형

    댓글