메소드 | 의미 | 결과 |
---|---|---|
document.getElementById('id') | HTML id속성으로 태그 선택하기 | id에 해당하는 태그 하나 |
document.getElementsByClassName('class') | HTML class속성으로 태그 선택하기 | class에 해당하는 태그 모음(HTMLCollection) |
document.getElementsByTagName('tag') | HTML 태그 이름으로 태그 선택하기 | tag에 해당하는 태그 모음(HTMLCollection) |
document.querySelector('css') | css 선택자로 태그 선택하기 | css 선택자에 해당하는 태그 중 가장 첫번째 태그 하나 |
document.querySelectorAll('css') | css 선택자로 태그 선택하기 | css 선택자에 해당하는 태그 모음(NodeList) |
length
프로퍼티가 있다.Array.isArray(유사배열)
의 리턴값은 false
다.
const btn = document.querySelector('#myBtn');
btn.onclick = function() {
console.log('Hello Codeit!');
};
<button id="myBtn" onclick="console.log('Hello Codeit!')">클릭!</button>
dir 메소드는 문자열 표시 형식으로 콘솔에 출력한다.
log
메소드는 파라미터로 전달받은 값을 위주로 출력dir
메소드는 객체의 속성을 좀 더 자세하게 출력dir
메소드는 객체의 유형이 먼저 출력되고, 특히 함수 부분에서는 클릭해서 펼쳤을 때 함수가 가진 속성들을 더 보여준다. (log
메소드는 펼쳐지지 않음)
console.log(str, num, bool, arr, obj, func);
console.dir(str, num, bool, arr, obj, func);
log
메소드는 여러 값을 쉼표로 구분해서 전달하면 전달받은 모든 값을 출력dir
메소드는 여러 값을 전달하더라도 첫 번째 값만 출력
const myDOM = document.body;
console.log(myDOM);
console.dir(myDOM);
→ 콘솔에서 값 자체를 확인하고 싶다면 log
메소드를, 객체의 속성들을 살펴보고 싶다면 dir
메소드를 활용하기
window
객체는 브라우저 창을 대변하면서 자바스크립트에서 최상단에 존재하는 객체.window.
을 생략할 수도 있다.프로퍼티 | 유형 | 결과 |
---|---|---|
element.children | 자식 요소 노드 | element의 자식 요소 모음(HTMLCollection) |
element.firstElementChild | 자식 요소 노드 | element의 첫 번째 자식 요소 하나 |
element.lastElementChild | 자식 요소 노드 | element의 마지막 자식 요소 하나 |
element.parentElement | 부모 요소 노드 | element의 부모 요소 하나 |
element.previousElementSibling | 형제 요소 노드 | element의 이전(previous) 혹은 좌측(left)에 있는 요소 하나 |
element.nextElementSibling | 형제 요소 노드 | element의 다음(next) 혹은 우측(right)에 있는 요소 하나 |
프로퍼티 | 유형 | 결과 |
---|---|---|
node.childNodes | 자식 노드 | node의 자식 노드 모음(NodeList) |
node.firstChild | 자식 노드 | node의 첫 번째 자식 노드 하나 |
node.lastChild | 자식 노드 | node의 마지막 자식 노드 하나 |
node.parentNode | 부모 노드 | node의 부모 요소 하나 |
node.previousSibling | 형제 노드 | node의 이전(previous) 혹은 좌측(left)에 있는 노드 하나 |
node.nextSibling | 형제 노드 | node의 다음(next) 혹은 우측(right)에 있는 노드 하나 |
브라우저가 HTML 코드를 해석할 때 각 코드들은 상황에 맞게 node를 생성하고 DOM 트리를 구성하는데,
HTML 태그는 요소 노드가 되고,
문자들은 텍스트 노드,
주석도 주석 노드로 DOM 트리에 반영된다.
outerHTML
은 새로운 값을 할당할 경우 요소 자체가 교체되어 버리기 때문에 주의innerHTML
과 마찬가지로 내부의 값을 완전히 새로운 값으로 교체한다textContent
는 텍스트만 다루기 때문에, 특수문자도 그냥 텍스트로 처리한// HTML 속성 (HTML attribute)
const tomorrow = document.querySelector('#tomorrow');
const item = tomorrow.firstElementChild;
const link = item.firstElementChild;
// elem.getAttribute('속성'): 속성에 접근하기
console.log(tomorrow.getAttribute('href'));
console.log(item.getAttribute('class'));
// elem.setAttribute('속성', '값'): 속성 추가(수정)하기
tomorrow.setAttribute('class', 'list'); // 추가
link.setAttribute('href', 'https://www.codeit.kr'); // 수정
// elem.removeAttribute('속성'): 속성 제거하기
tomorrow.removeAttribute('href');
tomorrow.removeAttribute('class');
// id 속성
console.log(tomorrow);
console.log(tomorrow.id);
// class 속성
console.log(item);
console.log(item.className);
// href 속성
console.log(link);
console.log(link.href);
console.log(tomorrow.href);
// elem.classList: add, remove, toggle
const item = tomorrow.children[1];
item.classList.add('done');
item.classList.remove('done');
item.classList.toggle('done');
// elem.className
today.children[1].className = 'done';
// style 프로퍼티
today.children[0].style.textDecoration = 'line-through';
today.children[0].style.backgroundColor = '#DDDDDD';
today.children[2].style.textDecoration = 'line-through';
today.children[2].style.backgroundColor = '#DDDDDD';
프로퍼티 | 내용 | 참고사항 |
---|---|---|
element.innerHTML | 요소 노드 내부의 HTML코드 문자열로 리턴 | 요소 안의 정보를 확인할 수도 있지만,내부의 HTML 자체를 수정할 때 좀 더 자주 활용 |
element.outerHTML | 요소 노드 자체의 전체적인 HTML 코드를 문자열로 리턴 | outerHTML은 새로운 값을 할당하면요소 자체가 교체되어 버리기 때문에 주의 |
element.textContent | 요소 노드 내부의 내용들 중에서 HTML을 제외하고 텍스트만 리턴 | textContent는 말그대로 텍스트만 다루기 때문에HTML태그를 쓰더라도 모두 텍스트로 처리됨 |
document.createElement('태그이름')
element.textContent, element.innerHTML, ...
element.prepend, element.append, element.after, element.before
element.remove()
대부분의 HTML 속성은 DOM 객체의 프로퍼티로 변환이 된다.
하지만, 표준 속성이 아닌 경우에는 프로퍼티로 변환이 안 된다. 아래 메소드를 활용하면 표준이 아닌 HTML 속성들도 다룰 수 있다.
element.getAttribute('속성')
element.setAttribute('속성', '값')
element.removeAttribute('속성')
element.style.styleName = 'value';
element.className
, element.classList
메소드 | 내용 | 참고사항 |
---|---|---|
classList.add | 클래스 추가하기 | 여러 개의 값을 전달하면 여러 클래스 추가 가능 |
classList.remove | 클래스 삭제하기 | 여러 개의 값을 전달하면 여러 클래스 삭제 가능 |
classList.toggle | 클래스 없으면 추가, 있으면 삭제하기 | 하나의 값만 적용 가능하고,두 번째 파라미터로 추가 또는 삭제 기능을 강제할 수 있음 |
<!DOCTYPE html>
<html lang="ko">
<head>
<meta charset="UTF-8">
<title>JS with Codeit</title>
</head>
<body>
<p>할 일 : <b field="title"></b></p>
<p>담당자 : <b field="manager"></b></p>
<p>상태 : <b field="status"></b></p>
<div>
상태 변경:
<button class="btn" status="대기중">대기중</button>
<button class="btn" status="진행중">진행중</button>
<button class="btn" status="완료">완료</button>
</div>
<script src="index.js"></script>
</body>
</html>
[status] {
padding: 5px 10px;
}
[status="대기중"] {
background-color: #FF6767;
color: #FFFFFF;
}
[status="진행중"] {
background-color: #5f62ff;
color: #FFFFFF;
}
[status="완료"] {
background-color: #07c456;
color: #FFFFFF;
}
[속성이름]
처럼 대괄호를 이용하면 대괄호 안에 있는 속성이름을 가진 태그들을 선택할 수 있고 [속성이름="값"]
처럼 작성하면, 좀 더 구체적으로 속성이름에 해당 값을 가진 태그들을 선택할 수도 있다.
const fields = document.querySelectorAll('[field]');
console.log(fields);
비표준 속성은 객체 형태의 데이터가 있을 때, 각 프로퍼티 값들이 들어갈 태그를 구분하는데 활용할 수도 있다.
const fields = document.querySelectorAll('[field]');
const task = {
title: '코드 에디터 개발',
manager: 'CastleRing, Raccoon Lee',
status: '',
};
for (let tag of fields) {
const field = tag.getAttribute('field');
tag.textContent = task[field];
}
getAttribute
메소드를 활용해서 속성값을 가져오고, setAttribute
메소드를 활용해서 속성값을 설정해주는 원리로 이벤트를 통해 실시간으로 스타일을 변경하거나 데이터를 변경하는데 활용할 수 있다.
const fields = document.querySelectorAll('[field]');
const task = {
title: '코드 에디터 개발',
manager: 'CastleRing, Raccoon Lee',
status: '',
};
for (let tag of fields) {
const field = tag.getAttribute('field');
tag.textContent = task[field];
}
const btns = document.querySelectorAll('.btn');
for (let btn of btns) {
const status = btn.getAttribute('status');
btn.onclick = function () {
fields[2].textContent = status;
fields[2].setAttribute('status', status);
};
}
!!! 비표준 속성을 사용해 코드를 작성했을 때 시간이 지나서 나중에 그 속성이 표준으로 등록되면 문제가 발생할 수 있다.
→ data-
로 시작하는 속성은 모두 dataset이라는 프로퍼티에 저장된다.
예를 들어서 data-status
라는 속성이 있다면, element.dataset.status
라는 프로퍼티에 접근해서 그 값을 가져올 수 있다.
<button class="btn" data-status="대기중">대기중</button>
<button class="btn" data-status="진행중">진행중</button>
<button class="btn" data-status="완료">완료</button>
이벤트 타입 | 설명 |
---|---|
mousedown | 마우스 버튼을 누르는 순간 |
mouseup | 마우스 버튼을 눌렀다 떼는 순간 |
click | 왼쪽 버튼을 클릭한 순간 |
dblclick | 왼쪽 버튼을 빠르게 두 번 클릭한 순간 |
contextmenu | 오른쪽 버튼을 클릭한 순간 |
mousemove | 마우스를 움직이는 순간 |
mouseover | 마우스 포인터가 요소 위로 올라온 순간 |
mouseout | 마우스 포인터가 요소에서 벗어나는 순간 |
mouseenter | 마우스 포인터가 요소 위로 올라온 순간 (버블링이 일어나지 않음) |
mouseleave | 마우스 포인터가 요소에서 벗어나는 순간 (버블링이 일어나지 않음) |
이벤트 타입 | 설명 |
---|---|
keydown | 키보드의 버튼을 누르는 순간 |
keypress | 키보드의 버튼을 누르는 순간 ('a', '5' 등 출력이 가능한 키에서만 동작하며, Shift, Esc 등의 키에는 반응하지 않음) |
keyup | 키보드의 버튼을 눌렀다 떼는 순간 |
이벤트 타입 | 설명 |
---|---|
focusin | 요소에 포커스가 되는 순간 |
focusout | 요소로부터 포커스가 빠져나가는 순간 |
focus | 요소에 포커스가 되는 순간 (버블링이 일어나지 않음) |
blur | 요소로부터 포커스가 빠져나가는 순간 (버블링이 일어나지 않음) |
이벤트 타입 | 설명 |
---|---|
change | 입력된 값이 바뀌는 순간 |
input | 값이 입력되는 순간 |
select | 입력 양식의 하나가 선택되는 순간 |
submit | 폼을 전송하는 순간 |
이벤트 타입 | 설명 |
---|---|
scroll | 스크롤 바가 움직일 때 |
이벤트 타입 | 설명 |
---|---|
resize | 윈도우 사이즈를 움직일 때 발생 |
프로퍼티 | 설명 |
---|---|
type | 이벤트 이름 ('click', 'mouseup', 'keydown' 등) |
target | 이벤트가 발생한 요소 |
currentTarget | 이벤트 핸들러가 등록된 요소 |
timeStamp | 이벤트 발생 시각(페이지가 로드된 이후부터 경과한 밀리초) |
bubbles | 버블링 단계인지를 판단하는 값 |
프로퍼티 | 설명 |
---|---|
button | 누른 마우스의 버튼 (0: 왼쪽, 1: 가운데(휠), 2: 오른쪽) |
clientX, clientY | 마우스 커서의 브라우저 표시 영역에서의 위치 |
pageX, pageY | 마우스 커서의 문서 영역에서의 위치 |
offsetX, offsetY | 마우스 커서의 이벤트 발생한 요소에서의 위치 |
screenX, screenY | 마우스 커서의 모니터 화면 영역에서의 위치 |
altKey | 이벤트가 발생할 때 alt키를 눌렀는지 |
ctrlKey | 이벤트가 발생할 때 ctrl키를 눌렀는지 |
shiftKey | 이벤트가 발생할 때 shift키를 눌렀는지 |
metaKey | 이벤트가 발생할 때 meta키를 눌렀는지 (window는 window키, mac은 cmd키) |
프로퍼티 | 설명 |
---|---|
key | 누른 키가 가지고 있는 값 |
code | 누른 키의 물리적인 위치 |
altKey | 이벤트가 발생할 때 alt키를 눌렀는지 |
ctrlKey | 이벤트가 발생할 때 ctrl키를 눌렀는지 |
shiftKey | 이벤트가 발생할 때 shift키를 눌렀는지 |
metaKey | 이벤트가 발생할 때 meta키를 눌렀는지 (window는 window키, mac은 cmd키) |
HTML의 속성이나 DOM 프로퍼티를 활용해 이벤트를 등록하는 방법 외에 Element.addEventListener('type', 'handler')
를 통해서 이벤트 핸들러를 등록할 수 있다.
addEventListener
메소드를 활용해서 이벤트 핸들러를 등록했다면, Element.removeEventListner('type', 'handler')
를 통해서 이벤트 핸들러를 삭제할 수 있다.
이벤트가 발생하면 이벤트 핸들러의 첫 번째 파라미터에는 자동으로 이벤트 객체가 전달된다.
이벤트 객체는 이벤트 종류마다 가지고 있는 프로퍼티가 다르며, 이벤트에 대한 유용한 정보들을 프로퍼티로 가지고 있다.
참고로 이벤트 버블링은 이벤트 객체의 stopPropagation
메소드로 전파를 막을 수 있다.
DOM 이벤트에서 정의한 이벤트 흐름
이벤트가 시작된 시점에서 위로 전파가 되는 현상
이벤트가 시작된 시점에서 아래로 전파가 되는 현상
버블링 개념을 활용하면 훨씬 효과적인 이벤트 관리를 할 수 있다. 예를 들어 자식 요소 각각에 이벤트 핸들러를 하나씩 등록할 필요 없이 부모 요소에서 한 번에 자식 요소들에 발생한 이벤트를 관리할 수도 있다.
이렇게 이벤트를 다루는 방식을 자식 요소의 이벤트를 부모 요소에 위임한다고 해서 이벤트 위임(Event Delegation)이라고 부른다.
브라우저에는 각 태그별 혹은 상황별로 기본적으로 약속된 동작들이 있다.
예를 들어 마우스 오른쪽 버튼을 클릭하면 상황에 맞는 메뉴 창이 뜬다거나, input
태그에 커서를 두고 키보드 키를 누르면 해당 값이 입력된다거나
그런데 만약 이러한 동작들을 막고 싶다면 이벤트 객체의 preventDefault
메소드를 통해 막을 수가 있다.
이벤트 타입 | 설명 |
---|---|
mousedown | 마우스 버튼을 누르는 순간 |
mouseup | 마우스 버튼을 눌렀다 떼는 순간 |
click | 왼쪽 버튼을 클릭한 순간 |
dblclick | 왼쪽 버튼을 빠르게 두 번 클릭한 순간 |
contextmenu | 오른쪽 버튼을 클릭한 순간 |
mousemove | 마우스를 움직이는 순간 |
mouseover | 마우스 포인터가 요소 위로 올라온 순간 |
mouseout | 마우스 포인터가 요소에서 벗어나는 순간 |
mouseenter | 마우스 포인터가 요소 위로 올라온 순간 (버블링이 일어나지 않음) |
mouseleave | 마우스 포인터가 요소에서 벗어나는 순간 (버블링이 일어나지 않음) |
이벤트 타입 | 설명 |
---|---|
keydown | 키보드의 버튼을 누르는 순간 |
keypress | 키보드의 버튼을 누르는 순간 ('a', '5' 등 출력이 가능한 키에서만 동작하며, Shift, Esc 등의 키에는 반응하지 않음) |
keyup | 키보드의 버튼을 눌렀다 떼는 순간 |
이벤트 타입 | 설명 |
---|---|
focusin | 요소에 포커스가 되는 순간 |
focusout | 요소로부터 포커스가 빠져나가는 순간 |
focus | 요소에 포커스가 되는 순간 (버블링이 일어나지 않음) |
blur | 요소로부터 포커스가 빠져나가는 순간 (버블링이 일어나지 않음) |
이벤트 타입 | 설명 |
---|---|
change | 입력된 값이 바뀌는 순간 |
input | 값이 입력되는 순간 |
select | 입력 양식의 하나가 선택되는 순간 |
submit | 폼을 전송하는 순간 |
이벤트 타입 | 설명 |
---|---|
scroll | 스크롤 바가 움직일 때 |
이벤트 타입 | 설명 |
---|---|
resize | 윈도우 사이즈를 움직일 때 발생 |
프로퍼티 | 설명 |
---|---|
type | 이벤트 이름 ('click', 'mouseup', 'keydown' 등) |
target | 이벤트가 발생한 요소 |
currentTarget | 이벤트 핸들러가 등록된 요소 |
timeStamp | 이벤트 발생 시각(페이지가 로드된 이후부터 경과한 밀리초) |
bubbles | 버블링 단계인지를 판단하는 값 |
프로퍼티 | 설명 |
---|---|
button | 누른 마우스의 버튼 (0: 왼쪽, 1: 가운데(휠), 2: 오른쪽) |
clientX, clientY | 마우스 커서의 브라우저 표시 영역에서의 위치 |
pageX, pageY | 마우스 커서의 문서 영역에서의 위치 |
offsetX, offsetY | 마우스 커서의 이벤트 발생한 요소에서의 위치 |
screenX, screenY | 마우스 커서의 모니터 화면 영역에서의 위치 |
altKey | 이벤트가 발생할 때 alt키를 눌렀는지 |
ctrlKey | 이벤트가 발생할 때 ctrl키를 눌렀는지 |
shiftKey | 이벤트가 발생할 때 shift키를 눌렀는지 |
metaKey | 이벤트가 발생할 때 meta키를 눌렀는지 (window는 window키, mac은 cmd키) |
프로퍼티 | 설명 |
---|---|
key | 누른 키가 가지고 있는 값 |
code | 누른 키의 물리적인 위치 |
altKey | 이벤트가 발생할 때 alt키를 눌렀는지 |
ctrlKey | 이벤트가 발생할 때 ctrl키를 눌렀는지 |
shiftKey | 이벤트가 발생할 때 shift키를 눌렀는지 |
metaKey | 이벤트가 발생할 때 meta키를 눌렀는지 (window는 window키, mac은 cmd키) |
HTML의 속성이나 DOM 프로퍼티를 활용해 이벤트를 등록하는 방법 외에 Element.addEventListener('type', 'handler')
를 통해서 이벤트 핸들러를 등록할 수 있다.
addEventListener
메소드를 활용해서 이벤트 핸들러를 등록했다면, Element.removeEventListner('type', 'handler')
를 통해서 이벤트 핸들러를 삭제할 수 있다.
이벤트가 발생하면 이벤트 핸들러의 첫 번째 파라미터에는 자동으로 이벤트 객체가 전달된다.
이벤트 객체는 이벤트 종류마다 가지고 있는 프로퍼티가 다르며, 이벤트에 대한 유용한 정보들을 프로퍼티로 가지고 있다.
참고로 이벤트 버블링은 이벤트 객체의 stopPropagation
메소드로 전파를 막을 수 있다.
DOM 이벤트에서 정의한 이벤트 흐름
이벤트가 시작된 시점에서 위로 전파가 되는 현상
이벤트가 시작된 시점에서 아래로 전파가 되는 현상
버블링 개념을 활용하면 훨씬 효과적인 이벤트 관리를 할 수 있다. 예를 들어 자식 요소 각각에 이벤트 핸들러를 하나씩 등록할 필요 없이 부모 요소에서 한 번에 자식 요소들에 발생한 이벤트를 관리할 수도 있다.
이렇게 이벤트를 다루는 방식을 자식 요소의 이벤트를 부모 요소에 위임한다고 해서 이벤트 위임(Event Delegation)이라고 부른다.
브라우저에는 각 태그별 혹은 상황별로 기본적으로 약속된 동작들이 있다.
예를 들어 마우스 오른쪽 버튼을 클릭하면 상황에 맞는 메뉴 창이 뜬다거나, input
태그에 커서를 두고 키보드 키를 누르면 해당 값이 입력된다거나
그런데 만약 이러한 동작들을 막고 싶다면 이벤트 객체의 preventDefault
메소드를 통해 막을 수가 있다.
client
프로퍼티는 클라이언트 영역 내에서 마우스의 좌표 정보를 담고있다.client
값은 그 순간 보여지는 화면을 기준으로 계산하기 때문에 스크롤 위치와는 무관하게 항상 보여지는 화면의 좌측 상단의 모서리 위치를 (0, 0)으로 계산한다.
offset
프로퍼티는 이벤트가 발생한 target이 기준.target
내에서 마우스의 X좌표 위치.target
내에서 마우스의 Y좌표 위치.offset
값은 이벤트가 발생한 대상을 기준으로 계산하기 때문에 스크롤 위치와는 무관하게 항상 대상의 좌측 상단의 모서리 위치를 (0, 0)으로 계산한다.
mouseover: 마우스 포인터가 요소 위로 올라온 순간
mouseenter: 마우스 포인터가 요소 위로 올라온 순간
mouseenter와 mouseleave는 버블링이 일어나지 않음.
→ 이벤트 핸들러가 자식 요소에까지 영향을 끼치게 하고싶은 경우에는 mouseover/mouseout
→ 자식 요소에는 영향을 끼치지 않고 해당 요소에만 이벤트 핸들러를 다루고자 한다면 mouseenter/mouseleave
값 | 내용 |
---|---|
0 | 마우스 왼쪽 버튼 |
1 | 마우스 휠 |
2 | 마우스 오른쪽 버튼 |
3 | X1 (일반적으로 브라우저 뒤로 가기 버튼) |
4 | X2 (일반적으로 브라우저 앞으로 가기 버튼) |
참고로 mouseenter, mouseleave, mouseover, mouseout, mousemove
처럼 마우스 이동과 관련된 이벤트에서는 이 값이 null
이나 undefined
가 아니라 0
이라는 점!!!
mouseenter, mouseleave, mouseover, mouseout
이벤트에는 relatedTarget
이라는 프로퍼티가 존재한다.
target
프로퍼티가 이벤트가 발생한 요소를 담고 있다면, relatedTarget
프로퍼티는 이벤트가 발생하기 직전(또는 직후)에 마우스가 위치해 있던 요소를 담고 있다.
이벤트 타입 | 설명 |
---|---|
keydown | 키보드의 버튼을 누르는 순간 |
keypress | 키보드의 버튼을 누르는 순간 ('a', '5' 등 출력이 가능한 키에서만 동작하며, Shift, Esc 등의 키에는 반응하지 않음) |
keyup | 키보드의 버튼을 눌렀다 떼는 순간 |
키보드 이벤트 객체에는 key
와 code
프로퍼티가 자주 사용된다.
key
는 사용자가 누른 키가 가지고 있는 값code
는 누른 키의 물리적인 위치이벤트 타입 | 설명 |
---|---|
focusin | 요소에 포커스가 되는 순간 |
focusout | 요소에 포커스가 빠져나가는 순간 |
focus | 요소에 포커스가 되는 순간 (버블링이 일어나지 않음) |
blur | 요소에 포커스가 빠져나가는 순간 (버블링이 일어나지 않음) |
change | 입력된 값이 바뀌는 순간 |
input | 값이 입력되는 순간 |
select | 입력 양식의 하나가 선택되는 순간 |
submit | 폼을 전송하는 순간 |
scroll
이벤트는 보통 window
객체에 이벤트 핸들러를 등록하고 window
객체의 프로퍼티와 함께 자주 활용된다.