문서 객체 모델(Document Object Model, DOM)은 웹 페이지 내의 모든 콘텐츠(HTML)를 계층화시켜 객체로 나타내는 모델이다. 여기서 중요한 단어는 객체이다.
// 배경을 파란색으로 변경하기
document.body.style.background = 'blue'
JavaScript에서 .
은 객체 내의 데이터 프로퍼티에 접근하는 문법이다. 첫 시작점이 document
객체인데 document
객체는 페이지의 기본 진입점이라고 볼 수 있다. 이 document
객체를 사용해서 페이지의 내용을 변경하거나 html 요소를 새로 만들거나 클래스를 부여하거나 스타일을 부여하는 등 여러가지를 할 수 있다.
아래는 DOM 객체 트리 구조를 시각화한 자료이다. 각각의 태그는 요소 노드(element node) 혹은 그냥 요소라고 하며 트리 구조를 구성한다. root 노드인 html
을 기준으로 head
, body
라는 자식 노드가 있다. 그리고 트리 구조로 계속 자식 노드들이 형성되어 있다.
document
라는 진입점에서 출발하여 원하는 요소 노드에 접근하기 위한 방법에 대해서 알아보자. 아래는 원하는 요소(ex: 로그인 버튼)에 접근하기 위해서 자주 사용할 함수들의 일부이다.
document.getElmentById()
document.getElementsByClassName()
document.getElementsByTagName()
document.querySelector()
document.querySelectorAll()
위 함수들은 document 객체에 있는 함수들이다. 이를 사용해서 원하는 요소에 접근할 수 있다. Element
인 경우가 있고 Elements
인 경우가 있다. 두 차이점을 고려하여 아래 HTML 구조에 대해서 어떻게 접근하는지 코드로 확인해보자.
<body>
<main>
<section>
<article class='myClass'>여기에 접근하고 싶습니다</article>
<article class='myClass'>여기가 아닙니다</article>
<article class='myClass'>여기가 아닙니다</article>
</section>
</main>
<footer>
<small id='contactEmail'>asdzxc@email.com</small>
</footer>
</body>
const myFirstClass = document.getElementsByClassName('myClass')[0];
const contactEmail = document.getElementById('contactEmail');
console.log(myFirstClass.innerHTML) // "여기에 접근하고 싶습니다"
contactEmail.style.color = 'green' // 글자색을 초록색으로 변경
getElemntsByClassName
에서는 elements 이므로 'myClass'
에 해당하는 요소를 담은 컬렉션이 반환된다. 따라서 여러 개중 첫 번째에 접근하기 위해 [0]
과 같이 배열의 요소에 접근하는 것처럼 하나를 특정해주어야 한다. 반면 id
는 고유한 값이기 때문에 getElementById
와 같이 접근하는 것 만으로 하나의 요소에 접근하게 된다.
브라우저는 HTML을 읽다가 <script>
태그를 만나면 DOM 생성을 멈추고 스크립트를 먼저 실행한다. 이런 브라우저의 동작 순서 때문에 발생하는 문제가 있다.
<script>
는 해당 스크립트 아래에 있는 DOM에 접근할 수 없게 된다.이런 부작용들을 피할 수 있는 몇 가지 방법이 있다. 스크립트를 페이지 맨 아래 놓는 것이 하나의 방법이 될 수 있다. 이렇게 하면 스크립트 위에 있는 요소에 접근할 수 있다. 또한, 페이지 콘텐츠 출력을 막지 않게 된다.
그런데 이 방법은 완벽한 해결책이 아니다. HTML 문서 자체가 아주 큰 경우를 가정해보자. 브라우저가 HTML 문서 전체를 다운로드 한 다음에 스크립트를 다운받게 하면 페이지가 정말 느려질 것이다.
이런 문제를 해결할 수 있는 <script>
속성이 있다. 바로 defer와 async이다.
이벤트는 무언가 일어났다는 신호이다. 클릭이나 스크롤 등의 이벤트가 발생했을 때 실행되는 함수를 핸들러(handler) 라고 부른다. 이 핸들러 사용자의 행동에 어떻게 반응할지를 JavaScript 코드로 구현한 것이다.
// 이벤트와 핸들러 문법의 일반적인 형태
element.addEventListener(event, handler, [options]);
element
는 접근할 요소를 뜻한다. 예를 들어 어떤 버튼이 클릭했을 때를 하나의 이벤트로 하고 싶다면 그 버튼 요소에 해당한다.(getElementsByClassName
, getElementbyId
, querySelector
등으로 접근한 요소)
addEventListener
라는 특별한 메소드는 핸들러를 관리할 수 있는 메소드이다. 이 메소드는 어떤 이벤트가 일어나기를 기다리고 있게 만드는 것이다.
addEventListener
의 첫번째 인자인 event
가 바로 이벤트의 타입이다. 첫 번째 인자의 위치에 들어갈 수 있는 이벤트들은 매우 종류가 많다.
ex) 'click'
, 'keydown'
, 'input'
addEventListener
의 두번째 인자인 handler
에 핸들러 함수가 들어가게 된다. 이벤트 함수가 사용자가 작성하게 될 코드가 들어가는 곳이다.
addEventListener
의 첫번째 인자 event
와 두번째 인자 handler
는 필수 인자이지만 세 번째 인자는 선택적으로 들어가는 인자로 필요할 때만 넣어주면 된다.
참고 자료