안녕하세요!
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)
- 텍스트: 태그가 품고 있는 (여는 태그와 닫는 태그 사이의) 텍스트
- 속성: 태그의 속성
그럼 뿌리 노드부터 차근차근 알아봅시다
- html: html 태그는 html문서의 모든 요소들을 품고 있습니다. 따라 노드 중에서도 뿌리 노드로 지칭합니다
- head, body: html의 자식 노드입니다. head와 body는 자매 관계입니다.
- title: head의 자식이자 html의 자손입니다. 텍스트를 품고 있습니다.
- 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
함수라고 해서 ()괄호를 붙이면 안된다는 점 유의해주세요!
+) 이벤트에 뭐가 있었지... 하는 분들은 이벤트 처리기를 복습하고 오세요!
+) 아니 함수가 왜 저렇게 생겼어... 하는 분들은 익명함수를 복습하고 오세요!
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말고도 안드로이드를 할 때에도 비슷하게 쓰이기 때문에 메서드들을 어떻게 사용하는지 직접 타이핑 해보면서 익혀보시고 꼭꼭 실습 해보시길 바랍니다!
'Programming Language > JavaScript' 카테고리의 다른 글
[JavaScript] 데이터 단위 변환기 토이 프로젝트 만들어보기 (0) | 2023.05.06 |
---|---|
[JavaScript] DOM 객체로 HTML 요소의 속성 바꾸기 (0) | 2023.05.05 |
[JavaScript] 이벤트와 이벤트 처리기 (0) | 2023.04.23 |
[JavaScript] 익명 함수, 즉시 실행 함수, 다양한 함수의 표현법 알기 (0) | 2023.04.23 |
[JavaScript] 자바 스크립트의 함수 알기 (0) | 2023.04.22 |