memostack
article thumbnail
블로그를 이전하였습니다. 2023년 11월부터 https://bluemiv.tistory.com/에서 블로그를 운영하려고 합니다. 앞으로 해당 블로그의 댓글은 읽지 못할 수 도 있으니 양해바랍니다.
반응형

HTML 문서에 js 추가시 주의할 점

브라우저는 html 문서를 위에서부터 아래로 한줄 씩 읽어 내려간다. 브라우저에서 아직 읽지 않은 요소를 js에서 참조하려고 하면, 해당 요소를 찾지 못하게 된다.

 

예를들어, 아래 코드를 보면

<!DOCTYPE html>
<html lang="ko">
<head>
    <meta charset="UTF-8" />
    <title>test</title>
    <link rel="stylesheet" href="./test.css" />
    
    <script type="text/javascript">
        var test = document.getElementById("test");
        test.innerHTML = "changed value!";
    </script>
</head>
<body>
    <div id="test">
        initial value
    </div>
</body>
</html>

만약, head 태그 내부와 같이 상단에 javascript를 추가 하게되면, 그 아래에 위치한 요소들은 (js를 읽는 시점에) 아직 브라우저에서 읽지 못했기 때문에 js 파일에서 특정 요소를 참조할 수 없다.

 

그래서 '개발자 도구'를 열어서 확인해보면 아래와 같이 참조할 수 없다는 오류를 확인할 수 있다.

Uncaught TypeError: Cannot set properties of null (setting 'innerHTML')

null에서 innerHTML을 찾을 수 없음

 

이 문제를 해결하는 방법은 2가지가 있다

 

방법 1. 참조하려는 요소보다 아래쪽에 js를 위치

간단하게 참조하려는 요소보다 아래쪽에 script를 위치시켜서, 브라우저에서 해당 요소를 분석한 뒤에 script를 실행시키면 된다.

<!DOCTYPE html>
<html lang="ko">
<head>
    <meta charset="UTF-8" />
    <title>test</title>
    <link rel="stylesheet" href="./test.css" />
</head>
<body>
    <div id="test">
        initial value
    </div>

    <!-- 아래쪽에 script를 위치시킨다 -->
    <script type="text/javascript">
        var test = document.getElementById("test");
        test.innerHTML = "changed value!";
    </script>
</body>
</html>

정상동작

오류없이 javascript가 실행되어, initial value가 changed value로 변경된다.

 

방법 2. script 태그의 defer를 활용

script 태그에는 defer 속성이 있는데, 해당 속성은 Boolean 값을 가진다.

  • true로 설정: 문서 파싱 후 script를 실행한다.
  • false로 설정: 문서 파싱하는 과정에서 script를 실행한다. (default)

 

그리고, js 파일로 분리하여 가지고 오도록해야 defer 속성이 활성화된다. (src 속성과 같이 사용되어야 하기 때문에)

<!DOCTYPE html>
<html lang="ko">
<head>
    <meta charset="UTF-8" />
    <title>test</title>
    <link rel="stylesheet" href="./test.css" />
    <script type="text/javascript" src="./test.js" defer></script>
</head>
<body>
    <div id="test">
        initial value
    </div>
</body>
</html>
var test = document.getElementById("test");
test.innerHTML = "changed value!";

정상동작

마찬가지로 정상적으로 원하던 결과가 나온다.

반응형
블로그를 이전하였습니다. 2023년 11월부터 https://bluemiv.tistory.com/에서 블로그를 운영하려고 합니다. 앞으로 해당 블로그의 댓글은 읽지 못할 수 도 있으니 양해바랍니다.
profile

memostack

@bluemiv_mm

포스팅이 좋았다면 "좋아요❤️" 또는 "구독👍🏻" 해주세요!