- 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
객체와 이벤트 리스너를 활용해보았습니다.
저번 포스팅에서 막막했던 감정이 이제는 이 이벤트 리스너를 어떻게 활용할 수 있을지에 대한 설렘을 바뀌어서 굉장히 좋네요!!
다음 포스팅에서는 다양한 폼 태그 요소를 다루며 여러 이벤트를 접목해보겠습니다.
마지막 과제인 단위변환계산기 프로젝트를 향해 조금만 더 가보도록 할게요!!