✅ HTML 요소의 동작 제어 목적으로 추가적인 정보를 제공합니다.
<HTML요소시작태그 어트리뷰트이름="어튜리뷰트값" />
<input id="user" type="text" value="ungmo2" />
🤔 어트리뷰트 종류
- 글로벌 어트리뷰트: id, class, style, title, lang, tabindex, draggable, hidden 등
- 이벤트 핸들러 어트리뷰트: onclick, onchange, onfocus, onblur, oninput, onkeypress, onkeydown, onkeyup, onmouseover, onsubmit, onload 등
- 특정 HTML 요소 어트리뷰트: 예) input: type, value, checked
😀 HTML 문서 파싱 시 HTML 어트리뷰트당 하나의 어트리뷰트 노드로 변환되어 요소 노드와 연결됩니다.
🤔 NamedNodeMap
객체
- 요소 노드의 모든 어트리뷰트 노드의 참조가 담긴 이터러블한 유사 배열 객체입니다.
- attributes 프로퍼티에 저장되어있습니다. (getter만 존재 하는 읽기 전용 접근자 프로퍼티)
<!DOCTYPE html>
<html>
<body>
<input id="user" type="text" value="ungmo2" />
<script>
const { attributes } = document.getElementById("user");
console.log(attributes);
// NamedNodeMap {0: id, 1: type, 2: value, id: id, type: type, value: value, length: 3}
console.log(attributes.id.value); // user
console.log(attributes.type.value); // text
console.log(attributes.value.value); // ungmo2
</script>
</body>
</html>
🤔 Element.protype.getAttribute/setAttribute
메서드
- 직접 HTML 어트리뷰트 값을 취득하거나 변경할 수 있습니다.
<!DOCTYPE html>
<html>
<body>
<input id="user" type="text" value="ungmo2" />
<script>
const $input = document.getElementById("user");
// value 어트리뷰트 값을 취득
const inputValue = $input.getAttribute("value");
console.log(inputValue); // ungmo2
// value 어트리뷰트 값을 변경
$input.setAttribute("value", "foo");
console.log($input.getAttribute("value")); // foo
</script>
</body>
</html>
🤔 Element.protype.hasAttribute/removeAttribute
메서드
hasAttribute
: 특정 HTML 어트리뷰트의 존재를 확인할 수 있습니다.removeAttribute
: 특정 HTML 어트리뷰트를 삭제할 수 있습니다.
<!DOCTYPE html>
<html>
<body>
<input id="user" type="text" value="ungmo2" />
<script>
const $input = document.getElementById("user");
// value 어트리뷰트의 존재 확인
if ($input.hasAttribute("value")) {
// value 어트리뷰트 삭제
$input.removeAttribute("value");
}
console.log($input.hasAttribute("value")); // false
</script>
</body>
</html>
🤔 DOM 프로퍼티
- 요소 노드는
상태(state)
를 가집니다. - 어트리뷰트 노드: 초기 상태
- DOM 프로퍼티: 최신 상태
🤔 어트리뷰트 노드
getAttribute
,setAttribute
메서드 사용하여 초기 상태 값을 취득하거나 변경합니다.
<!DOCTYPE html>
<html>
<body>
<input id="user" type="text" value="ungmo2" />
<script>
document.getElementById("user").getAttribute("value"); // ungmo2
document.getElementById("user").setAttribute("value", "foo");
</script>
</body>
</html>
🤔 DOM 프로퍼티
- 사용자의 입력에 의한 상태 변화에 반응하여 언제나 (동적으로 변경) 최신 상태 를 유지합니다.
<!DOCTYPE html>
<html>
<body>
<input id="user" type="text" value="ungmo2" />
<script>
const $input = document.getElementById("user");
// 사용자가 input 요소의 입력 필드에 값을 입력할 때마다 input 요소 노드의
// value 프로퍼티 값, 즉 최신 상태 값을 취득한다. value 프로퍼티 값은 사용자의 입력에
// 의해 동적으로 변경된다.
$input.oninput = () => {
console.log("value 프로퍼티 값", $input.value); // DOM 프로퍼티 값
};
// getAttribute 메서드로 취득한 HTML 어트리뷰트 값, 즉 초기 상태 값은 변하지 않고 유지된다.
console.log("value 어트리뷰트 값", $input.getAttribute("value")); // 어트리뷰트 값
</script>
</body>
</html>
<!DOCTYPE html>
<html>
<body>
<input id="user" type="text" value="ungmo2" />
<script>
const $input = document.getElementById("user");
// DOM 프로퍼티에 값을 할당하여 HTML 요소의 최신 상태를 변경한다.
$input.value = "foo";
console.log($input.value); // foo
// id 어트리뷰트와 id 프로퍼티는 사용자 입력과 관계없이 항상 동일한 값으로 연동한다.
$input.id = "foo";
// getAttribute 메서드로 취득한 HTML 어트리뷰트 값, 즉 초기 상태 값은 변하지 않고 유지된다.
console.log($input.getAttribute("value")); // ungmo2
console.log($input.id); // foo
console.log($input.getAttribute("id")); // foo
</script>
</body>
</html>
🤔 HTML 어트리뷰트와 DOM 프로퍼티의 대응 관계
- id 어트리뷰트와 id 프로퍼티는 1:1 대응하며, 동일한 값으로 연동합니다.
- input 요소의 value 어트리뷰트와 value 프로퍼티는 1:1 대응하며,
value 어트리뷰트는 초기 상태를, value 프로퍼티는 최신 상태를 가집니다. - class 어트리뷰트는 className, classList 프로퍼티와 대응합니다.
- for 어트리뷰트는 htmlFor 어트리뷰트 프로퍼티와 1:1 대응합니다.
예외 - td 요소의 cospan 어트리뷰트는 대응하는 프로퍼티가 존재하지 않습니다.
- textContent 프로퍼티는 대응하는 어트리뷰트가 존재하지 않습니다.
- 어트리뷰트 이름은 대소문자를 구별하지 않지만 대응하는 프로퍼티 키는 카멜 케이스를 따릅니다. (maxlength -> maxLength)
✅ DOM 프토퍼티 값의 타입 은 문자열이 아닐 수 있다.
<!DOCTYPE html>
<html>
<body>
<input type="checkbox" checked />
<script>
const $checkbox = document.querySelector("input[type=checkbox]");
// getAttribute 메서드로 취득한 어트리뷰트 값은 언제나 문자열이다.
console.log($checkbox.getAttribute("checked")); // ''
// DOM 프로퍼티로 취득한 최신 상태 값은 문자열이 아닐 수도 있다.
console.log($checkbox.checked); // true
</script>
</body>
</html>
🤔 data 어트리뷰트
data- 접두사
- 사용자 정의 어트리뷰트와 자바스크립트 간에 데이터를 교환할 수 있습니다.
🤔 dataset 프로퍼티
- HTML 모든 요소 data 어트리뷰트의 정보를 제공하는
DOMStringMap
객체를 반환합니다. - 카멜 케이스로 변환
<!DOCTYPE html>
<html>
<body>
<ul class="users">
<li id="1" data-user-id="7621" data-role="admin">Lee</li>
<li id="2" data-user-id="9524" data-role="subscriber">Kim</li>
</ul>
<script>
const users = [...document.querySelector(".users").children];
const user = users.find((user) => user.dataset.userId === "7621");
console.log(user.dataset.role); // "admin"
user.dataset.role = "subscriber";
// dataset 프로퍼티는 DOMStringMap 객체를 반환한다.
console.log(user.dataset); // DOMStringMap {userId: "7621", role: "subscriber"}
</script>
</body>
</html>
✅ 존재하지 않는 이름을 키로 사용하여 dataset 프로퍼티에 할당 시 HTML 요소에 data 어트리뷰트가 추가 됩니다.
<!DOCTYPE html>
<html>
<body>
<ul class="users">
<li id="1" data-user-id="7621">Lee</li>
<li id="2" data-user-id="9524">Kim</li>
</ul>
<script>
const users = [...document.querySelector(".users").children];
const user = users.find((user) => user.dataset.userId === "7621");
user.dataset.role = "admin";
console.log(user.dataset);
/*
DOMStringMap {userId: "7621", role: "admin"}
-> <li id="1" data-user-id="7621" data-role="admin">Lee</li>
*/
</script>
</body>
</html>
🤔 HTMLElement.prototype.style 프로퍼티
getter
,setter
모두 존재 하는 접근자 프로퍼티- 요소 노드의 인라인 스타일 을 취득하거나 추가 또는 변경
<!DOCTYPE html>
<html>
<body>
<div style="color: red">Hello World</div>
<script>
const $div = document.querySelector("div");
// 인라인 스타일 취득
console.log($div.style); // CSSStyleDeclaration { 0: "color", ... }
$div.style.color = "blue";
// 인라인 스타일 추가
$div.style.width = "100px";
$div.style.height = "100px";
$div.style.backgroundColor = "yellow";
</script>
</body>
</html>
🤔 CSSStyleDeclaration
- style 프로퍼티 참조시
CSSStyleDeclaration
타입의 객체를 반환합니다. - 다양한 CSS 프로퍼티에 대응하는 프로퍼티
- 값 할당 시 해당 CSS 프로퍼티가 인라인 스타일로 HTML 요소에 추가되거나 변경됩니다.
- ❗CSS 프토퍼티는 케밥 케이스,
CSSStyleDeclaration
객체의 프로퍼티는 카멜 케이스를 따릅니다.
$div.style.backgroundColor = "yellow"; // CSSStyleDeclaration 객체의 프로퍼티
$div.style["background-color"] = "yellow"; // 케밥 케이스의 CSS 프로퍼티 사용 시 작성방법
$div.style.width = "100px"; // 단위 지정이 필요한 CSS 프로퍼티 값은 반드시 지정
- ❗클래스 DOM 프로퍼티:
className
과classList
자바스크립트에서는 class 예약어
🤔 className
setter
와getter
모두 존재 하는 접근자 프로퍼티- HTML 요소의 class 어트리뷰트 값을 취득하거나 변경
- 문자열을 반환하기 때문에 공백으로 구분된 여러 개의 클래스를 반환하는 경우 불편
<!DOCTYPE html>
<html>
<head>
<style>
.box {
width: 100px;
height: 100px;
background-color: antiquewhite;
}
.red {
color: red;
}
.blue {
color: blue;
}
</style>
</head>
<body>
<div class="box red">Hello World</div>
<script>
const $box = document.querySelector(".box");
console.log($box.className); // 'box red'
$box.className = $box.className.replace("red", "blue");
</script>
</body>
</html>
🤔 classList
-> DOMTokenList
객체
- class 어트리뷰트 정보를 담은
DOMTokenList
객체를 반환 - 컬랙션 객체로서 유사 배열 객체이면서 이터러블
<!DOCTYPE html>
<html>
<head>
<style>
.box {
width: 100px;
height: 100px;
background-color: antiquewhite;
}
.red {
color: red;
}
.blue {
color: blue;
}
</style>
</head>
<body>
<div class="box red">Hello World</div>
<script>
const $box = document.querySelector(".box");
// .box 요소의 class 어트리뷰트 정보를 담은 DOMTokenList 객체를 취득
// classList가 반환하는 DOMTokenList 객체는 HTMLCollection과 NodeList와 같이
// 노드 객체의 상태 변화를 실시간으로 반영하는 살아 있는(live) 객체다.
console.log($box.classList);
// DOMTokenList(2) [length: 2, value: "box blue", 0: "box", 1: "blue"]
// .box 요소의 class 어트리뷰트 값 중에서 'red'만 'blue'로 변경
$box.classList.replace("red", "blue");
</script>
</body>
</html>
// class="box red"
$box.classList.add("foo"); // -> class="box red foo"
$box.classList.add("bar", "baz"); // -> class="box red foo bar baz"
// class="box red bar baz"
$box.classList.remove("foo"); // -> class="box red bar baz"
$box.classList.remove("bar", "baz"); // -> class="box red"
$box.classList.remove("x"); // 무시 -> class="box red"
// class="box red"
$box.classList.item(0); // -> "box"
$box.classList.item(1); // -> "red"
// class="box red"
$box.classList.contains("box"); // -> true
$box.classList.contains("blue"); // -> false
// class="box red"
$box.classList.replace("red", "blue"); // -> class="box blue"
- 인수로 전달한 문자열과 일치하는 클래스가 존재하면 제거, 존재하지 않으면 추가합니다.
class="box blue"
$box.classList.toggle("foo"); // -> class="box blue foo"
$box.classList.toggle("foo"); // -> class="box blue"
- 두번째 인수 설정
- 조건식 평가 결과가 true이면 강제로 첫 번째 인수로 받은 문자열을 추가하고, false이면 강제로 첫 번째 인수로 전달받은 문자열을 제거합니다.
// class 어트리뷰트에 강제로 'foo' 클래스를 추가
$box.classList.toggle("foo", true); // -> class="box blue foo"
// class 어트리뷰트에서 강제로 'foo' 클래스를 제거
$box.classList.toggle("foo", false); // -> class="box blue"
이 밖에 forEach, entries, keys, value, supports 메서드를 제공합니다.
🤔 getComputedStyle(element[, pseudo])
:
- 모든 CSS 스타일 참조
- 첫 번째 인수로 전달한 요소 노드에 적용되어 있는 평가된 스타일을
getComputedStyle
객체에 담아 반환합니다.링크 스타일, 임베딩 스타일, 인라인 스타일, 자바스크립트에서 적용한 스타일, 상속된 스타일, 기본(user agent) 스타일 등 모든 스타일 조합
<!DOCTYPE html>
<html>
<head>
<style>
body {
color: red;
}
.box {
width: 100px;
height: 50px;
background-color: cornsilk;
border: 1px solid black;
}
</style>
</head>
<body>
<div class="box">Box</div>
<script>
const $box = document.querySelector(".box");
// .box 요소에 적용된 모든 CSS 스타일을 담고 있는 CSSStyleDeclaration 객체를 취득
const computedStyle = window.getComputedStyle($box);
console.log(computedStyle); // CSSStyleDeclaration
// 임베딩 스타일
console.log(computedStyle.width); // 100px
console.log(computedStyle.height); // 50px
console.log(computedStyle.backgroundColor); // rgb(255, 248, 220)
console.log(computedStyle.border); // 1px solid rgb(0, 0, 0)
// 상속 스타일(body -> .box)
console.log(computedStyle.color); // rgb(255, 0, 0)
// 기본 스타일
console.log(computedStyle.display); // block
</script>
</body>
</html>
- 의사 요소를 지정하는 문자열을 전달할 수 있다.
- 의사 요소가 아닌 일반 요소의 경우 두 번째 인수는 생략한다.
<!DOCTYPE html>
<html>
<head>
<style>
.box:before {
content: "Hello";
}
</style>
</head>
<body>
<div class="box">Box</div>
<script>
const $box = document.querySelector(".box");
const computedStyle = window.getComputedStyle($box, ":before");
console.log(computedStyle.content); // "Hello"
</script>
</body>
</html>
- W3C가 WHATWG가 만든 HTML과 DOM의 공통된 표준
- 2018년 4월, 구글, 애플, 마이크로소프트, 모질라로 구성된 WHATWG이 만드는 단일 표준
레벨 | 표준 문서 URL |
---|---|
DOM Level 1 | https://www.w3.org/TR/REC-DOM-Level-1 |
DOM Level 2 | https://www.w3.org/TR/DOM-Level-2-Core |
DOM Level 3 | https://www.w3.org/TR/DOM-Level-3-Core |
DOM Level 4 | https://dom.spec.whatwg.org |