안녕하세요. 이번에는 스크립트로 특정 dom 요소를 접근할 경우
스크립트가 실행되는 시점에 따른 문제가 발생하는 경우와 그에 대한 해결책에 대해 알아보겠습니다.

접근 요소가 생성되기 전에 실행되는 경우.

<!DOCTYPE html>
<html lang="en">
  <head>
    <meta charset="UTF-8" />
    <meta name="viewport" content="width=device-width, initial-scale=1.0" />
    <meta http-equiv="X-UA-Compatible" content="ie=edge" />
    <title>Static Template</title>
    <script>
      var itemValue = document.querySelector("#item").value;
      function getItemValue() {
        console.log(itemValue);
      }
    </script>
  </head>

  <body>
    <div id="wrapper">
      <form action="">
        <input type="text" id="item" />
        <input type="button" value="확인" onclick="getItemValue()" />
      </form>
    </div>
  </body>
</html>

이런 경우  itemValue 는 undefined 가 됩니다.

웹 페이지의 코드는 위에서부터 한줄씩 순차적으로 실행되기 때문에

스크립트가 실행되는 시점에는 아직 input id=”item”이 생성된 상태가 아니기 때문이죠.

접근 요소가 생성된 후에 실행되는 경우.

<!DOCTYPE html>
<html lang="en">
  <head>
    <meta charset="UTF-8" />
    <meta name="viewport" content="width=device-width, initial-scale=1.0" />
    <meta http-equiv="X-UA-Compatible" content="ie=edge" />
    <title>Static Template</title>
  </head>

  <body>
    <div id="wrapper">
      <form action="">
        <input type="text" id="item" />
        <input type="button" value="확인" onclick="getItemValue()" />
      </form>
    </div>
    <script>
      var itemValue = document.querySelector("#item").value;
      function getItemValue() {
        console.log(itemValue);
      }
    </script>
  </body>
</html>

script 가 실행되는 시점을 input 태그 다음으로 작성해두었습니다.

이렇게되면 input이 생성된 후에 스크립트가 실행되므로 정상적으로 값을 조회 할 수 있는것이죠.

다만 모든 경우에 스크립트를 요소보다 하단에 위치시킬 수는 없습니다.

그럴때 사용 할 수 있는 방법은 실행 시점을 조절하는 것입니다.

실제 요소가 생성된 후에 호출되는 함수 또는 window.onload 또는 jquery 의 $(document).ready({}); 에서 작성하는 것 입니다.

각각의 방식으로 코드를 바꿔보겠습니다.

실제 요소가 생성된 후에 호출되는 함수에서 요소 접근

<!DOCTYPE html>
<html lang="en">
  <head>
    <meta charset="UTF-8" />
    <meta name="viewport" content="width=device-width, initial-scale=1.0" />
    <meta http-equiv="X-UA-Compatible" content="ie=edge" />
    <title>Static Template</title>
    <script>
      function getItemValue() {
        var itemValue = document.querySelector("#item").value;
        console.log(itemValue);
      }
    </script>
  </head>

  <body>
    <div id="wrapper">
      <form action="">
        <input type="text" id="item" />
        <input type="button" value="확인" onclick="getItemValue()" />
      </form>
    </div>
  </body>
</html>

간단한 코드에서는 이렇게 쓰는게 깔끔하고 좋은것 같습니다.

물론 추후에 코드가 복잡해지면 이 방식을 사용하지 못하는 경우가 있을 수 있고 코드의 중복이나 유지보수의 어려움도 생길 수 있습니다.

window.onload 사용

<!DOCTYPE html>
<html lang="en">
  <head>
    <meta charset="UTF-8" />
    <meta name="viewport" content="width=device-width, initial-scale=1.0" />
    <meta http-equiv="X-UA-Compatible" content="ie=edge" />
    <title>Static Template</title>
    <script>
      window.onload = function() {
        document.getElementById("btn1").addEventListener("click", function(e) {
          var itemValue = document.querySelector("#item").value;
          console.log(itemValue);
        });
      };
    </script>
  </head>

  <body>
    <div id="wrapper">
      <form action="">
        <input type="text" id="item" />
        <input type="button" id="btn1" value="확인" />
      </form>
    </div>
  </body>
</html>

이런식으로 스크립트 코드를 모두 onload 안에서 처리해버리면됩니다.
( 물론 무조건 onload에 넣어야 하는건 아니고, 실제 요소가 로드된 후에 사용되어야만 하는 코드들을 넣어주시면 좋습니다. )

코드가 작성된 위치에서 실행되어야하는 전역변수(?)들도 있으니 그건 유도리있게.. ^^;;

우리의 영원한 친구(?) jQuery 님을 등장시켜봅시다.

<!DOCTYPE html>
<html lang="en">
  <head>
    <meta charset="UTF-8" />
    <meta name="viewport" content="width=device-width, initial-scale=1.0" />
    <meta http-equiv="X-UA-Compatible" content="ie=edge" />
    <title>Static Template</title>
    <script src="https://code.jquery.com/jquery-1.12.4.min.js"></script>
    <script>
      $(document).ready(function() {
        $("#btn1").on("click", function() {
          var itemValue = $("#item").val();
          console.log(itemValue);
        });
      });
    </script>
  </head>

  <body>
    <div id="wrapper">
      <form action="">
        <input type="text" id="item" />
        <input type="button" id="btn1" value="확인" />
      </form>
    </div>
  </body>
</html>

jQuery가 참 편해요 ㅎㅎ

TMI로 위의 코드들을 쭉 보시면 아시겠지만 window.onload 와 jquery document ready 사용시에는 input onclick 을 제거하고 이벤트 리스너를 설정하는 방식으로 하였습니다.

왜냐면 input onclick 에서 함수를 호출하려면 window.onload 와 document.ready 등에서 변수만 처리하고 전역 함수를 별도로 선언해줘야하는게 일관성이 없고 깔끔하지 않은것 같아서 이런식으로 바꾸었습니다. 

이상으로 스크립트 실행 시점과 그에 따른 오류를 방지하기 위한 방법에 대해 알아보았습니다.

감사합니다. 😄