3. 이벤트와 DOM
이번 강좌에서는 자바스크립에서 사용자 이벤트를 처리하는 방법과 동적인 콘텐츠 핸들링을 위해 필요한 문서객체 모델(DOM)이 무엇인지 배우게 됩니다.
이 강의를 통해 웹페이지에서 발생하는 이벤트를 자바스크립트 코드와 연계할 수 있고 DOM을 통해 콘텐츠 혹은 디자인을 동적으로 핸들링 할 수 있습니다.
01: 이벤트(Event)
일반적으로 프로그래밍 언어에서 이벤트라고 하면 사용자의 동작 혹은 프로그램에서 발생하는 특정한 상황을 의미 합니다. 이벤트가 발생하면 보통 사전에 정의된 특정 코드가 실행되고 그에 따라 기능이 동작하거나 화면이 변경되는 등의 변화가 발생 합니다.
- 웹 브라우저가 알려주는 HTML요소에 대한 사건의 발생을 의미.
- 자바스크립트는 이벤트에 반응하여 특정 동작을 수행할 수 있음.
- 입력양식으로 부터 사용자의 입력값을 가져올 수 있음.
- HTML이벤트속성은 자바스크립트 구문을 직접 실행 하거나 함수를 호출할 수 있다.
1) HTML 이벤트
HTML에서 발생하는 이벤트는 주로 마우스 및 입력양식에서 발생하며 문서의 로딩과 관련한 특별한 이벤트를 포함합니다. 다음은 대표적인 이벤트 목록 입니다.
이벤트명 | 설명 |
---|---|
click | 클릭시 발생 |
change | 변동이 있을시 발생 |
focus | 포커스를 얻었을때 발생 |
keydown | 키를 눌렀을때 발생 |
keyup | 키에서 손을 땟을때 발생 |
load | 문서의 로드가 완료 되었을때 발생 |
unload | 문서가 언로드 되었을때 발생 |
resize | 윈도우 크기가 변경될 경우 발생 |
mouseover | 마우스가 특정 객체 위로 올려졌을 시에 발생 |
mousedown | 마우스를 클릭 했을때 발생 |
mouseout | 마우스가 특정 객체 밖으로 나갔을 때 발생 |
mousemove | 마우스가 움직였을 때 발생 |
mouseup | 마우스에서 손을 땟을때 발생 |
select | option 태그 등에서 선택을 했을때 발생 |
submit | 입력양식이 제출 요청 될때 발생 |
전체 이벤트 목록은 w3schools.com에서 참고하기 바랍니다.
2) 이벤트 핸들러
이벤트 핸들러는 이벤트발생을 감지하고 처리할 코드를 수행하는 역할을 담당합니다. HTML 태그의 속성으로 지정하거나 자바스크립트에서 DOM엘리먼트의 속성에 콜백 함수를 정의하는 형식으로 사용할 수 있습니다. 이벤트 핸들러는 앞의 이벤트 이름의 앞에 on을 붙여 사용합니다.
HTML 속성으로 정의
이벤트를 감지하기 위한 HTML 태그의 속성에 이벤트 핸들러를 기술하는 방식 입니다. 보통 입력양식에 작성하게 됩니다.
<input type="button" value="Button" onclick="alert('버튼 클릭됨!!')"></input>
- onclick 속성에 자바스크립트 코드를 직접 작성하거나 이벤트 처리를 위해 구현한 함수를 호출합니다.
- onXXX 를 이용해 여러 이벤트 핸들러 속성을 부여하는 것도 가능 합니다.
자바스크립트 에서 정의
자바스크립트 코드를 사용해 DOM 엘리먼트 즉, 특정 HTML 태그를 선택해 속성으로 이벤트 발생시 호출될 콜백 메서드를 정의하는 형식 입니다.
<script>
document.getElementById('b1').onclick = function() {alert("버튼 클릭됨!!")}
</script>
<body>
<input type="button" id="b1">
</body>
- document.getElementById() 메서드는 HTML문서에서 지정한 id 속성을 찾아 바인딩 합니다.
- 이벤트 발생시 할당된 함수부가 호출 되어 콜백 함수 라고 합니다.
02: DOM(Document Object Model)
1) DOM 개요
문서객체모델이라고 하며 HTML 혹은 XML문서의 구조화된 표현을 제공하는 표준입니다. HTML에서는 자바스크립트가 DOM 구조
에 접근할 수 있는 방법이 제공되며 이를 통해 문서 구조, 스타일, 내용
등을 변경 할 수 있습니다.
자바스크립트는 DOM을 이용하여 HTML의 태그, 속성, 스타일 등을 추가/삭제 하거나 변경할 수 있습니다.
Document Node
document 객체를 말하며 DOM 트리에 접근하기 위한 최상위 노드로 모든 DOM 트리에 접근하기 위한 시작점이 됩니다.
Element Node
HTML 구성 요소 즉 대표적으로 대그를 의미합니다. 문서내 태그들은 모두 Element Node 들 입니다. 각각의 Element Node 는 다시 Attribute와 Text Node를 가집니다.
Attribute Node
태그들의 속성을 객체화한 노드를 말합니다. 만일 특정 태그의 속성에 접근하려면 Attribute Node를 사용해야 합니다.
Text Node
태그의 텍스트를 객체화한 노드입니다. 자식 노드를 가질 수 없으며 DOM 트리구조의 최종단 노드가 됩니다.
2) HTML 요소 핸들링
자바스크립트에서 HTML DOM 요소에 접근하는 방법은 태그이름, 아이디, 클래스, 이름 등을 이용해 특정 노드 객체를 선택하는 것입니다. CSS 의 셀렉터와 유사 하다고 볼 수 있습니다.
예를들어 버튼에서 이벤트가 발생 했을 때 특정 입력양식의 입력값을 읽어 값에 따라 화면 구성을 변경 해야 하는 경우 id로 특정 입력양식 노드를 찾아서 입력값을 가지고 온 다음 다시 화면 변경을 위해 특정 태그의 id값으로 해당 노드의 값이나 속성을 변경하는 등의 작업을 거치게 됩니다.
HTML 요소선택
getElement(s)ByXXX() 를 이용해 특정 요소(태그) 노드를 가지고 옵니다.
document.getElementsByTagName("tag_name")
document.getElementById("id_name")
document.getElementsByClassName("class_name")
document.getElementsByName("name_attribute")
- 모든
getElementsByXXX()
함수의 경우 동일 조건의 모든 노드를 목록으로 가져옴. getElementByName()
의 경우 태그의 name 속성으로 노드를 찾음.
let elist = document.getElementsByTagName("h2");
for(let el of elist) {
console.log("##"+el.tagName);
}
쿼리 셀렉터
getElementByXXX() 와 달리 단일 메서드로 원하는 요소를 찾을 수 있습니다. 단 유효한 CSS 셀렉터를 사용해야 하며 그렇지 않으면 예외가 발생 합니다.
document.querySelector("#main, #title, #footer");
document.querySelectorAll("p.note, p.tip")
- 콤마로 구분된 여러 셀렉터를 나열 할 수 있으며 해당 조건에 맞는 첫번째 노드만 가져옴.
- 해당 조건의 모든 노드를 가지고 오려면 querySelectorAll()을 사용 함.
HTML 요소 생성, 제거, 추가
HTML 요소를 선택하는것 이외에도 특정 요소를 생성, 제거 하거나 자식 노드를 추가하는 것도 가능합니다.
document.createElement(element)
document.removeChild(element)
document.appendChild(element)
document.replaceChild(element)
3) HTML 요소의 속성 행들링
HTML 요소를 선택한 다음에는 해당 요소의 속성과 텍스트 노드에 접근할 수 있습니다. 물론 해당 요소내에 다른 요소들을 포함하고 있다면 마찬가지로 getElement(s)XXX()
함수를 사용해 자식노드들을 가지고 올 수 있습니다.
HTML 요소의 속성값 변경
해당 태그의 속성값을 변경할 수 있습니다. 이 경우 원래 HTML 소스가 바뀌는 것이 아니라 동적으로 내용만 변경되고 브라우저에 반영됩니다.
element.setAttribute(attribute, value)
element.getAttribute(attribute, value)
element.removeAttribute(attribute)
다음 예제는 title-img
라는 이름의 id 값으로 img 태그를 가져와 src
속성을 b.jpg
로 변경하는 예 입니다. 이벤트와 연결해서 실행ㅎ면 동적으로 이미지가 바뀌게 됩니다.
const el = document.getElementById("title-img");
el.setAttribute('src','b.jpg');
HTML 이벤트핸들러 추가
해당 요소의 이벤트를 처리하는 방법으로 이벤트에서 살펴본것 처럼 이벤트 속성에 콜백 함수를 할당하는 형식으로 이벤트 핸들러를 추가할 수 있습니다.
document.getElementById("id_name").onclick = function(){ code };
addEventHandler()
를 이용한 이벤트 핸들러 추가
이벤트 요소를 추가하기 위한 가장 구조적인 방법으로 onclick 속성에 콜백 함수를 구현하는 것 보다 좋은 방법입니다.
document.getElementById("id_name").addEventHandler("click", function(){ code });
텍스트 노드 변경
해당 태그의 태그 바디에 있는 텍스트 노드의 값을 변경하기 위해서는 innerHTML 혹은 innerText 속성을 사용할 수 있습니다.
element.innerHTML = '<tag>text</tag>';
element.innerText = 'text';
- innerHTML 은 태그 바디에 다른 HTML태그와 자식노드를 포함한 텍스트 를 처리할 때 사용.
- innerText는 단순한 텍스트만을 처리할 때 사용.
- innerText는 CSS에 종속적으로 CSS에 의해 hidden 처리가 되어 있다면 텍스트노드를 읽을 수 없다.
- 따라서 가능하면 innerHTML사용을 권장.
03: 디자인 요소 변경
자바스크립트에서의 이벤트 처리는 대부분 화면을 동적으로 변경하는것과 관련이 있습니다. DOM 요소를 이용해 특정 영역에 데이터를 표현하거나 혹은 감출 수 있으며 CSS 디자인 속성을 변경해 모양이나 색상등을 변경하는 것도 가능합니다.
1) 디자인 요소 변경
디자인 변경은 CSS의 기본적인 구조와 동작원리를 이해하고 있다면 어려울것이 없다. 해당 요소의 style 속성변경, style 객체변경, 클래스 지정등의 방법으로 변경이 가능합니다.
style 속성변경
모든 HTML 태그는 style 속성을 가질수 있으므로 다음과 같이 setAttribute로 style 속성을 변경할 수 있습니다.
document.getElementById('box1').setAttribute('style','background-color:yellow');
- 이 방법은 인라인 스타일시트와 같은 방법이며 구조적이지 않아 권장되지 않음.
style 객체 변경
style 속성 대신 요소의 style 객체의 속성값들을 변경하는 형식 입니다.
document.getElementById('box1').style.backgroundColor = 'yellow';
- 이방법은 좀 더 구조적인 방법이며 프로그램 친화적인 형태임.
- css 디자인 속성 이름은
-
로 연결되지만 이경우Camel Case
로 연결해야 함. - 예를 들어
background-color
속성은backgroundColor
와 같이 사용. - style 속성 변경보다는 좋은 방법이지만 많은 디자인 속성을 변경할때는 바람직 하지 않음.
클래스 지정
별도의 디자인 클래스를 지정해 놓고 해당 요소의 class 속성을 지정하는 형태 입니다.
document.getElementById('box1').className = 'bgyellow';
- 이경우 별도의 디자인 클래스가 정의 되어 있어야 함.
- 가장 권장되는 방법임.
2) 화면 숨기기
화면 구성요소를 상황에 따라 숨기거나 보여주는 방법은 UI 측면에서 매우 유용합니다. CSS 를 이용해 요소를 보여주거나 숨기는 두가지 방법은 다음과 같습니다.
display:none
요소를 숨기며 요소가 차지하는 공간도 함께 사라집니다. 다시 보이게 하려면 속성을 block 으로 변경하면 됩니다.
document.getElementById('box1').style.display = 'none';
visibility:hidden
요소를 숨기며 차지하는 공간도 유지하는 속성 입니다. width, height 가 지정되어 있으면 내용은 보이지 않아도 공간은 존재하게 됩니다. 다시 보이게 하려면 visible 이라고 하면 됩니다.
document.getElementById('box1').style.visibility = 'hidden';
참고 자료
- W3Schools.com JS 강좌: https://www.w3schools.com/js/default.asp
- Mozilla JS 안내서 : https://developer.mozilla.org/ko/docs/Web/JavaScript/Guide
- Codecademy JS 무료강좌: https://www.codecademy.com/learn/introduction-to-javascript