
- DOM 객체란 무엇인가
- document
- DOM 트리
- DOM 객체로 HTML 문서의 요소 가져오기
- id를 통해 요소에 접근하기
- class를 통해 요소에 접근하기
- querySelector()와 querySelectorAll()
- DOM에서 이벤트 처리하기
- DOM요소에 직접 이벤트 처리기 연결
- addEventListener() 사용하기
안녕하세요!
트윅스스터디 그 네 번째 과제에서는 DOM 객체와 이벤트 리스너를 배워보도록 하겠습니다.
저번 과제에서 "대체 DOM이 뭐야?" 하는 궁금증이 생겼었는데 이번에 공부하게 되어서 참 다행입니다..
그럼 알아볼까요?
(Document Object Model) 객체가 무엇인가요?DOM이란 문서 객체 모델입니다.
문서 객체 모델, 즉 DOM은 웹페이지(HTML 혹은 XML)의 콘텐츠 및 구조, 그리고 스타일 요소를 구조화시켜 표현하여 프로그래밍 언어가 해당 문서에 접근하여 읽고 조작할 수 있도록 API를 제공하는 일종의 인터페이스입니다.
쉽게 말해 스크립팅 언어(JS)가 쉽게 웹페이지에 접근하여 조작할 수 있게끔 연결시켜주는 역할을 담당합니다.
그럼 여기서 전의 포스팅을 봤다면 생각이 나실겁니다.
아! DOM을 이용해서 이벤트 리스너를 사용할 수 있겠구나!
Document 객체Document객체는 웹페이지 그 자체를 의미합니다.
웹페이지 그 자체라는 것은 document가 웹 문서 자체를 가리킨다는 소리입니다.
때문에 document를 활용하여 html문서를 수정할 수도 있습니다.
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
</head>
<body>
<script>
document.write("JS는 재밌당");
</script>
</body>
</html>
위의 코드를 실행한 뒤 F12키를 눌러 개발자 모드를 실행하면 아래와 같은 화면이 나오게 됩니다.
어? 뭐죠??
분명 html문서에는 아무것도 적혀있지 않았는데 웹페이지에 JS는 재밌당문자열이 적혔습니다.
이것이 바로 document로 웹페이지를 수정한 것입니다.
document가 웹페이지 그 자체이기 때문에 document.write()는 웹페이지에 해당 문자열을 적으라는 의미가 되어 JS는 재밌당이라는 문자열이 적히게 된 것이죠.
자바스크립트로 DOM을 사용하기 위해서는 DOM의 구조에 대해 이해를 하는 것이 좋은데요.
기본적인
DOM tree의 구조는 노드들의 계층 구조로 이루어져있습니다.
계층구조로 이루어져 있기 때문에 부모-자식 관계, 형제관계를 표현하는 비선형 자료구조를 나타냅니다.
아래의 DOM tree 구조예시를 보며 더 알아봅시다!
<!DOCTYPE html>
<html lang="en">
<head>
<title>Document</title>
</head>
<body>
<h2>안녕하세요</h2>
<p>반갑습니다.</p>
</body>
</html>
위의 HTML문서에서의 DOM 구조는 어떻게 되어 있을까요?
바로 위와 같은 구조로 이루어져 있습니다.
자세히 설명하기 전에 위와 같은 DOM 트리에서 사용하는 용어들을 한 번 정리하고 갈까요??
(element)그럼 위의 DOM 구조를 차근차근 분석해보도록 하죠!
document : 웹페이지 그 자체를 나타냅니다. document는 html문서의 모든 요소를 품고 있습니다. 뿌리 노드입니다.html : html태그는 모든 html문서의 요소를 품고 있습니다. document의 자식 노드입니다.head, body : html의 자식노드이자 title, h2, p태그의 부모입니다. document의 자손이기도 합니다. 둘은 형제관계입니다.title : head의 자식노드이자 텍스트(Document)의 부모노드입니다. h2, p : body의 자식노드이자 텍스트(안녕하세요, 반갑습니다.)의 부모노드입니다. 각각은 형제관계입니다.이제 트리구조에 대해 감이 오시나요??
자, 이제 DOM이 무엇인지에 대해 감이 오셨을 겁니다.
그럼 이 DOM을 활용하여 이벤트를 처리하기 전에 먼저 event handler 연결을 하는 법을 알아보도록 할까요!!
먼저 id를 통해 요소에 접근해봅시다.
id를 통해 요소에 접근하기 위해서는 document.getElementById('id')를 통해 하나의 객체 그 자체의 값을 넘겨받아야 합니다.
한 번 예제를 볼까요??
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
<script defer src="js/id.js"></script>
</head>
<body>
<button id="btn1"> click me! </button>
</body>
</html>
var button1 = document.getElementById("btn1");
console.log(button1);
위의 소스를 실행한 뒤 개발자모드에 들어가면 console부분에 id가 btn1인 button객체가 출력이 된 것을 확인할 수 있습니다.
js파일을 연결할 때 주의할 점은 script src로만 하면 제대로된 값이 나오지 않습니다.
script defer src로 해주세요!
이것을 모르고 있던 필자는 클릭했을 때 값이 나오지 않아 당황했답니다..
이번에는 class명을 통해 요소에 접근하는 방법을 익혀보도록 하겠습니다.
class명으로 접근하기 위해서는 document.getElementByClassName()을 활용하여야 합니다.
그럼 예제를 볼까요?
<!DOCTYPE html>
<html lang="en">
<head>
<title>Document</title>
<script defer src="js/class.js"></script>
</head>
<body>
<h1>클래스를 이용한 선택</h1>
<ul>
<li class="odd">첫 번째 아이템이에요!</li>
<li>두 번째 아이템이에요!</li>
<li class="odd">세 번째 아이템이에요!</li>
<li>네 번째 아이템이에요!</li>
<li class="odd">다섯 번째 아이템이에요!</li>
</ul>
</body>
</html>
var selectedItem = document.getElementsByClassName("odd"); // 클래스가 "odd"인 모든 요소를 선택함.
for (var i = 0; i < selectedItem.length; i++) {
selectedItem.item(i).style.color = "red"; // 선택된 모든 요소의 텍스트 색상을 변경함.
console.log(selectedItem);
}
위의 소스를 실행하면 아래와 같이 홀수번째의 줄만 빨간색으로 바뀌며 console창에 selectedItem배열이 출력되게 됩니다.

console.log(selectedItem);이 하나의 요소가 아니네요?
이유는 class는 중복 사용이 가능하기 때문입니다.
그래서 odd라는 클래스를 가진 것들이 모두 selectedItem의 요소가 된 것이죠.
이것으로 클래스명으로 가져온 객체는 배열로 저장된다는 것을 알 수 있었습니다.
앞으로 같은 기능을 하는 객체는 같은 클래스로 묶어 관리해야겠네요~
근데요 여러분.
클래스명과 아이디명으로 접근하지 않아도 접근할 수 있는 방법이 또 있습니다.
바로 querySelector()와 querySelectorAll()인데요,
노드.querySelector(선택자) : 지정된 선택자와 일치하는 도큐먼트의 첫 번째 element를 반환합니다. 단, 일치하는 요소가 없다면 null을 반환합니다.노드.querySelectorAll(선택자) : 지정된 셀렉터 그룹에 일치하는 도큐먼트의 element list를 나타냅니다. 지정된 셀렉터가 없는 경우에는 비어있는 NodeList로 반환합니다. 앞에서 아이디명이나 클래스명으로 객체를 받아올 때는 해당 이름으로만 표시를 했었죠?
하지만 querySelector()에서는 id는 #id명으로 class는 .class명으로 선택자를 입력해야합니다.
차이점이 있으니 주의해주세요!
그럼 예제를 보러 갈까요?
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
<script defer src="js/querySelector.js"></script>
</head>
<body>
<!-- 생략 -->
<button id="firstBtn">첫번째버튼</button>
<h1 class="title">title1</h1>
<h1 class="title">title2</h1>
<h1 class="title">title3</h1>
</body>
</html>
var firstBtn = document.querySelector("#firstBtn");
console.log(firstBtn);
var titles = document.querySelectorAll(".title");
console.log(titles);
위의 소스코드를 실행하게 된다면 아래와 같이 console창에 출력되게 됩니다.

근데 무언가 getElementById(), getElementByClassName()과 querySelector()의 차이점이 보이지 않으신가요??
출력 사진을 보면
getElementById(),getElementByClassName()은HTMLCollection으로 출력이 된 것에 반해
querySelector()querySelectorAll()는node()이거나NodeList로 출력이 되었습니다.
차이점이 있다는 것을 인지하고 넘어가주세요!
이제 요소를 불러오는 방법을 익히셨네요!
그럼 바로 DOM에서 이벤트를 처리해봅시다.
이벤트 처리기의 함수가 간단할 때에는 DOM요소에 직접 함수를 연결할 수 있습니다.
변수.on이벤트명 = 함수
<!DOCTYPE html>
<html lang="en">
<head>
<title>Document</title>
<script defer src="js/DOM_Event.js"></script>
</head>
<body>
<button id="btn1">버튼</button>
</body>
</html>
var button = document.getElementById("btn1");
button.onclick = function() {
console.log("버튼 클릭!");
};
버튼을 클릭하는 click이벤트를 실행한다면 "버튼 클릭!"이라는 텍스트가 console에 출력되게 됩니다.

물론 함수로 만들어진 것을 연결해주어도 됩니다.
js파일을 다음과 같이 변경한 뒤 실행을 한다면
function doClick() {
console.log("버튼 클릭! ver2.");
}
var button1 = document.getElementById("btn1");
button1.onclick = doClick;
똑같이 버튼을 클릭하면 console창에 "버튼 클릭! ver2."텍스트가 출력되게 됩니다.
!주의! - doClick가 함수라고해서 ()를 붙이면 안 됩니다.
필자는 button1.onclick = doClick();으로 작성했다가 오류가 나는 결과를 맞이했답니다.
자바스크립트의 함수에 대해 잘 모르시는 분이라면 아래의 글들을 읽어보세요!
자바스크립트 함수알기
자바스크립트의 익명 함수가 뭔가요?
addEventListener() 사용하기이벤트 처리기를 연결하는 다른 방법으로는 addEventListener()가 있습니다.
요소.addEventListener(이벤트, 함수);
handleEvent()메서드를 포함하는 객체 또는 js 함수여야 합니다.이벤트 처리는 다음과 같은 형식으로 할 수 있습니다.
그럼 바로 예제를 볼까요??
<!DOCTYPE html>
<html lang="en">
<head>
<title>Document</title>
<script defer src="js/EventListener.js"></script>
</head>
<body>
<button id="firstBtn">첫번째버튼</button>
</body>
</html>
var button = document.querySelector("#firstBtn");
function dbClick() {
console.log("dbclick");
}
button.addEventListener("click", () => {
console.log("click!");
});
button.addEventListener("dblclick", dbClick);
button.addEventListener("mouseover", function() {
console.log("mouseover!");
})

click dbclick mouseover와 addEventListener를 활용하여 버튼에 이벤트를 할당해주었습니다.
다양한 함수를 사용해보면 좋겠네요!!
(주의) dbclick은 dblclick으로 바꿔주어야 제대로 작동이 됩니다
필자는 멋모르고 dbclick으로 했다가 click만 주구장창나오는 현상을 맞닥뜨렸답니다.
이번 포스팅에서는 이벤트를 처리할 수 있는 DOM객체와 이벤트 리스너를 활용해보았습니다.
저번 포스팅에서 막막했던 감정이 이제는 이 이벤트 리스너를 어떻게 활용할 수 있을지에 대한 설렘을 바뀌어서 굉장히 좋네요!!
다음 포스팅에서는 다양한 폼 태그 요소를 다루며 여러 이벤트를 접목해보겠습니다.
마지막 과제인 단위변환계산기 프로젝트를 향해 조금만 더 가보도록 할게요!!