[JavaScript] DOM 객체와 이벤트 리스너 (TweeksStudy:0)

Haeun Noh·2023년 6월 6일
0
post-thumbnail

0606


  • DOM 객체란 무엇인가
    • document
    • DOM 트리
  • DOM 객체로 HTML 문서의 요소 가져오기
    • id를 통해 요소에 접근하기
    • class를 통해 요소에 접근하기
    • querySelector()와 querySelectorAll()
  • DOM에서 이벤트 처리하기
    • DOM요소에 직접 이벤트 처리기 연결
    • addEventListener() 사용하기

안녕하세요!
트윅스스터디 그 네 번째 과제에서는 DOM 객체와 이벤트 리스너를 배워보도록 하겠습니다.

저번 과제에서 "대체 DOM이 뭐야?" 하는 궁금증이 생겼었는데 이번에 공부하게 되어서 참 다행입니다..
그럼 알아볼까요?



🧁1. DOM 객체

👉1.1. DOM (Document Object Model) 객체가 무엇인가요?

DOM이란 문서 객체 모델입니다.

문서 객체 모델, 즉 DOM은 웹페이지(HTML 혹은 XML)의 콘텐츠 및 구조, 그리고 스타일 요소를 구조화시켜 표현하여 프로그래밍 언어가 해당 문서에 접근하여 읽고 조작할 수 있도록 API를 제공하는 일종의 인터페이스입니다.

쉽게 말해 스크립팅 언어(JS)가 쉽게 웹페이지에 접근하여 조작할 수 있게끔 연결시켜주는 역할을 담당합니다.

그럼 여기서 전의 포스팅을 봤다면 생각이 나실겁니다.
아! DOM을 이용해서 이벤트 리스너를 사용할 수 있겠구나!


👉1.2. 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는 재밌당이라는 문자열이 적히게 된 것이죠.


👉1.3. DOM 트리

자바스크립트로 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 트리에서 사용하는 용어들을 한 번 정리하고 갈까요??


  • 노드 (node) : 웹 문서의 요소 (element)
  • 텍스트 : 태그가 품고 있는 텍스트

그럼 위의 DOM 구조를 차근차근 분석해보도록 하죠!


  1. document : 웹페이지 그 자체를 나타냅니다. documenthtml문서의 모든 요소를 품고 있습니다. 뿌리 노드입니다.
  2. html : html태그는 모든 html문서의 요소를 품고 있습니다. document의 자식 노드입니다.
  3. head, body : html의 자식노드이자 title, h2, p태그의 부모입니다. document의 자손이기도 합니다. 둘은 형제관계입니다.
  4. title : head의 자식노드이자 텍스트(Document)의 부모노드입니다.
  5. h2, p : body의 자식노드이자 텍스트(안녕하세요, 반갑습니다.)의 부모노드입니다. 각각은 형제관계입니다.

이제 트리구조에 대해 감이 오시나요??



🧁2. DOM 객체로 HTML 문서의 요소 가져오기

자, 이제 DOM이 무엇인지에 대해 감이 오셨을 겁니다.

그럼 이 DOM을 활용하여 이벤트를 처리하기 전에 먼저 event handler 연결을 하는 법을 알아보도록 할까요!!


👉2.1. id를 통해 요소에 접근하기

먼저 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부분에 idbtn1button객체가 출력이 된 것을 확인할 수 있습니다.

출처 - 주경야독 티스토리

js파일을 연결할 때 주의할 점은 script src로만 하면 제대로된 값이 나오지 않습니다.
script defer src로 해주세요!
이것을 모르고 있던 필자는 클릭했을 때 값이 나오지 않아 당황했답니다..


👉2.2. class를 통해 요소에 접근하기

이번에는 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의 요소가 된 것이죠.

이것으로 클래스명으로 가져온 객체는 배열로 저장된다는 것을 알 수 있었습니다.
앞으로 같은 기능을 하는 객체는 같은 클래스로 묶어 관리해야겠네요~


👉2.3. querySelector()와 querySelectorAll()

근데요 여러분.
클래스명과 아이디명으로 접근하지 않아도 접근할 수 있는 방법이 또 있습니다.

바로 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로 출력이 되었습니다.

차이점이 있다는 것을 인지하고 넘어가주세요!



🧁3. DOM에서 이벤트 처리하기

이제 요소를 불러오는 방법을 익히셨네요!
그럼 바로 DOM에서 이벤트를 처리해봅시다.


👉3.1. 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();으로 작성했다가 오류가 나는 결과를 맞이했답니다.


자바스크립트의 함수에 대해 잘 모르시는 분이라면 아래의 글들을 읽어보세요!
자바스크립트 함수알기
자바스크립트의 익명 함수가 뭔가요?


👉3.2. 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 mouseoveraddEventListener를 활용하여 버튼에 이벤트를 할당해주었습니다.
다양한 함수를 사용해보면 좋겠네요!!


(주의) dbclick은 dblclick으로 바꿔주어야 제대로 작동이 됩니다
필자는 멋모르고 dbclick으로 했다가 click만 주구장창나오는 현상을 맞닥뜨렸답니다.



이번 포스팅에서는 이벤트를 처리할 수 있는 DOM객체와 이벤트 리스너를 활용해보았습니다.
저번 포스팅에서 막막했던 감정이 이제는 이 이벤트 리스너를 어떻게 활용할 수 있을지에 대한 설렘을 바뀌어서 굉장히 좋네요!!

다음 포스팅에서는 다양한 폼 태그 요소를 다루며 여러 이벤트를 접목해보겠습니다.
마지막 과제인 단위변환계산기 프로젝트를 향해 조금만 더 가보도록 할게요!!



profile
Tistory로 옮기게 되었습니다. @haeunnohh

0개의 댓글