Programming Language/JavaScript

[JavaScript] DOM 객체와 이벤트 처리

  • -

안녕하세요!

4번째 과제에서는 이번 시즌에 가장 중요하다고 볼 수 있는 DOM객체와 이벤트 처리에 대해 알아보도록 하겠습니다

DOM이란?

DOM 이란 Document Object Model의 약자입니다. 번역하자면 문서 객체 모델인데요. 여기서의 문서는 HTML 문서를 말한다고 이해하시면 됩니다.

document

<body>
<script>
    console.log(document);
</script>

<h1></h1>
<section></section>
</body>

위와 같은 HTML문서를 실행하고 개발자 모드에 들어가면

콘솔에 document가 출력되고, 펼쳤을 때 웹 문서의 소스를 볼 수 있습니다.

이를 통해 document는 웹 문서 자체를 가리키는 DOM요소 중 하나라는 것을 알 수 있습니다.

 

document가 웹 문서 자체를 가리키기 때문에 수정 또한 가능합니다.

document.write()를 활용해 문서를 수정해 보겠습니다.

<body>
    <script>
        document.write("<h2>안녕하세요</h2>");
        console.log(document);
    </script>
    <section></section>
</body>
</html>

body 에는 h2태그가 없지만 document.write()로 HTML 문서에 <h2> 안녕하세요 </h2>

를 작성한 것입니다.

DOM 트리

자바 스크립트로 DOM을 조작하기 위해서는 DOM의 구조에 대해 이해하셔야 합니다.

<html>
<head>
    <title>DOM 공부하기</title>
</head>
<body>
    <h1>DOM을 알아봅시다</h1>
    <p>DOM 구조는 트리 모양입니다.</p>
</body>
</html>

 

 

위와 같은 HTML 문서에서 DOM 구조는 어떻게 되어 있을까요?

HTML문서는 위와 같은 구조로 이루어져 있습니다. 

하나하나 살펴보기 전에!

위와 같은 DOM트리에서 사용하는 용어들을 정리하겠습니다

  • 노드: 웹 문서의 요소(element)
  • 텍스트: 태그가 품고 있는 (여는 태그와 닫는 태그 사이의) 텍스트
  • 속성: 태그의 속성

 

 

그럼 뿌리 노드부터 차근차근 알아봅시다

  1. html: html 태그는 html문서의 모든 요소들을 품고 있습니다. 따라 노드 중에서도 뿌리 노드로 지칭합니다
  2. head, body: html의 자식 노드입니다. head와 body는 자매 관계입니다.
  3. title: head의 자식이자 html의 자손입니다. 텍스트를 품고 있습니다.
  4. h1, p: body의 자식이자 html의 자손 입니다. 각각 텍스트를 품고 있으며, 서로 자매 관계입니다.

 

<section>
	<h1>안녕하세요</h1>
        <div>
            <h2>감사합니다</h2>
        </div>
</section>

위의 코드를 보고 DOM 구조를 떠올리실 수 있으신가요? 

DOM 구조를 파악하기 힘드시다면 직접 DOM 구조를 그려보면서 이해해 보시길 바랍니다.

 

 

DOM 요소에 접근하기

이제 가장 하이라이트 event handler 연결을 알아봅시다!


전 과제에서는 HTML 요소에 이벤트 핸들러를 연결했지만, 이러한 방식은 태그와 스크립트 소스가 섞여 있어 복잡한 프로그램에는 적합하지 않습니다. 

 

그러 럼 HTML과 스크립트 소스를 분리하는 방법을 알아봅시다 

id를 통해 요소에 접근하기

먼저 id를 통해 요소에 접근해 보겠습니다. id를 통해 요소에 접근하려면 getElementById() 함수를 이용합니다.

요소명.getElementById("id명");

id는 html 태그의 속성으로 태그에 고유한 이름을 준다고 생각하시면 됩니다.

 

다음 코드로 실습을 해보겠습니다.

<!DOCTYPE html>
<html lang="en">
<head>
    <title>Document</title>
    <script defer src="js\EventHandlerDemo.js"></script>
</head>
<body>
    <button id="btn1"> click me! </button>
</body>
</html>

button의 id가 btn1인 것을 확인하실 수 있습니다. 

이제 스크립트 소스(js파일)에서 btn1에 접근하겠습니다.

var button1 = document.getElementById("btn1");
console.log(button1);

실행 결과 >>

document.getElementById() 메서드를 이용하여 html문서에 아이디가 btn1 인 요소를 가져왔습니다.

getElementByID()를 사용할 때 유의해야 하는 점은 id를 호출할 때 #을 붙이지 않는다입니다.

 

저는 습관적으로 id를 불러올 때 습관적으로 "#아이디명"을 써서 항상 오류가 발생하는데, 여러분들은 유의하셔서 그런 실수 안 하시길 바랍니다... 

class를 통해 요소에 접근하기

다음으로 class를 통해 요소에 접근하는 방법은 바로 document.getElementByClassName() 메서드를 이요하는 것입니다.

요소명.getElementByClassName("class명");

여기서 id와 class의 다른 점은 바로

 

id는 중복될 수 없지만, class는 중복이 가능하다 인데요, 그 점을 활용하여 실습 진행하겠습니다.

 

HTML

<body>
    <!-- <button id="btn1"> click me! </button> -->
    <button class="btn"> 버튼1 </button>
    <button class="btn"> 버튼2 </button>
    <button class="btn"> 버튼3 </button>
</body>

class가 btn인 버튼 3개를 만들었습니다

 

JS

var buttons = document.getElementsByClassName("btn");
console.log(buttons);

스크립트 소스에 document.getElementByClassName() 메서드를 이용하여 class가 btn인 버튼 세 개를 모두 가져왔습니다. 그럼 이 버튼은 어떻게 저장될까요?

 

실행결과 >>

버튼 세 개가 모두 배열로 저장되어 있습니다.

같은 기능을 하는 버튼들은 class로 묶어 사용하기 편하겠죠?

 

querySelector(), querySelectorAll()

여러분 사실... id와 class 구분 없이 모두 불러올 수 있는 메서드가 있습니다.

바로 querySelctor(), querySelectorAll() 메서드입니다. 

노드.getQuerySelector(선택자);
노드.getQuerySelectorAll();

여기서 노드는 DOM구조에서 언급한 노드입니다.

선택자는 id, class, 태그 이름을 말합니다. id는 #id명으로, class는. class명으로 선택자를 입력합니다.

 

html

<body>
	<!-- 생략 -->
    <button id="firstBtn">첫번째버튼</button>
    <h1 class="title">title1</h1>
    <h1 class="title">title2</h1>
    <h1 class="title">title3</h1>
</body>

위와 같은 html 문서에서 #firstBtn과. title을 가져오도록 하겠습니다

 

js

var firstBtn = document.querySelector("#firstBtn");
console.log(firstBtn);

var titles = document.querySelectorAll(".title");
console.log(titles);

실행 결과 >>

여기서 getElementById(), getElementByClassName()과 querySelector()의 차이를 아실 수 있습니다.

 

querySelector()와 querySelectorAll() 메서드의 반환값은 노드이거나 노드 리스트입니다. 

앞에서 살펴본 메서드들은 반환값이 HTMLCollection입니다.

HTMLCollection 객체는 HTML요소 (<button>, <p>와 같은 요소들)만 저장됩니다. 하지만 querySelector()는 반환값이 노드이기 때문에 DOM 트리의 텍스트, 속성 노드까지 제어할 수 있습니다.

 

갑자기 위에서 HTML 컬렉션이니... 노드니... 하고 조금 어려운 말을 했는데, 일단은 아~ 그렇구나~라고 생각하시면서 지금 당장은 querySelector()가 더 제어하기 편하겠구나라고 이해하시면 충분합니다!

 

 

지금까지의 실습 코드

 

HTML

<!DOCTYPE html>
<html lang="en">
<head>
    <title>Document</title>
    <script defer src="js\EventHandlerDemo.js"></script>
</head>
<body>
    <button id="btn1"> click me! </button>
    
    <button class="btn"> 버튼1 </button>
    <button class="btn"> 버튼2 </button>
    <button class="btn"> 버튼3 </button>

    <button id="firstBtn">첫번째버튼</button>
    <h1 class="title">title1</h1>
    <h1 class="title">title2</h1>
    <h1 class="title">title3</h1>
</body>
</html>

JS

var button1 = document.getElementById("btn1");
console.log(button1);

var buttons = document.getElementsByClassName("btn");
console.log(buttons);

var firstBtn = document.querySelector("#firstBtn");
console.log(firstBtn);

var titles = document.querySelectorAll(".title");
console.log(titles);



 

 

 

 

DOM에서 이벤트 처리하기

자 이제 요소까지 불러왔으니 DOM에서 이벤트를 처리해 봅시다. 

DOM요소에 이벤트 처리기 연결

먼저 DOM 요소에 함수를 직접 연결하는 방법에 대해 알아보겠습니다.

 

이벤트 처리기의 함수가 간달할 때에는 DOM요소에 직접 함수를 연결할 수 있습니다.

변수.on+이벤트명 = 함수

 

var button1 = document.getElementById("btn1");
button1.onclick = function() {
    console.log("버튼 클릭!")
};

button1 을 클릭하게 되면 콘솔창에 다음과 같이 출력됩니다.

익명함수가 아닌 함수를 연결하는것도 물론 가능합니다!

function doClick() {
    console.log("버튼 클릭!");
};

button1.onclick = doClick; //doClick() X

함수라고 해서 ()괄호를 붙이면 안된다는 점 유의해주세요!

 

 

+) 이벤트에 뭐가 있었지... 하는 분들은 이벤트 처리기를 복습하고 오세요!

+) 아니 함수가 왜 저렇게 생겼어... 하는 분들은 익명함수를 복습하고 오세요!

https://hulrud.tistory.com/17

 

[JavaScript] 이벤트와 이벤트 처리기

 

hulrud.tistory.com

https://hulrud.tistory.com/16

 

 

[JavaScript] 익명 함수, 즉시 실행 함수, 다양한 함수의 표현법 알기

안녕하세요! 저번 함수 알아보기 게시물에 이어서 함수를 더 편리하고 간편하게 사용할 수 있는 방법들을 공부해 보겠습니다. 익명함수 익명함수는 말 그대로 이름이 없는 함수입니다. 전 게시

hulrud.tistory.com

 

 

 

 

 

addEventListener() 사용하기

이벤트 처리기를 연결하는 다른 방법은 addEventListner() 메서드를 사용하는 것입니다.

요소.addEventListner(이벤트, 함수);
  • 이벤트: 이벤트 유형(click, mouseover 등) 을 지정합니다. 이때, 앞에서 봤던 메서드와 달리 on을 붙이지 않습니다
  • 함수: 이벤트가 발생하면 실행할 명령과 함수를 지정합니다

 

실습을 통해 알아봅시다

var firstBtn = document.querySelector("#firstBtn");

firstBtn.addEventListener("dbclick", () => {
    console.log("EventListner로 이벤트 처리하기");
});

firstBtn.addEventListener("click", doClick);

firstBtn.addEventListener("mouseover", function(){
    console.log("mouseover");
});

여러분이 함수들을 모두 잊으셨을 것 같아... 여러 형태로 사용해봤습니다.

 


실행 결과 >>

이렇게 addEventListener() 메서드 안에 함수를 선언하면 특정 이벤트에서 어떤 명령을 실행하는지 확인하기에 용이합니다.

 


오늘 과제는 꽤나... 양이 많죠...? 

사실 오늘 과제가 제일제일제일 중요하다고도 할 수 있습니다.

이벤트 처리는 js말고도 안드로이드를 할 때에도 비슷하게 쓰이기 때문에 메서드들을 어떻게 사용하는지 직접 타이핑 해보면서 익혀보시고 꼭꼭 실습 해보시길 바랍니다! 

 

 

 

Contents

포스팅 주소를 복사했습니다

이 글이 도움이 되었다면 공감 부탁드립니다.