브라우저는 웹페이지를 만나면 HTML을 읽어(파싱(parsing)) DOM 객체를 생성한다. 요소 노드(element node)에서 대부분의 표준 HTML 속성(attribute)은 DOM 객체의 프로퍼티(property)가 된다.
그런데 속성-프로퍼티가 항상 일대일로 매핑되지는 않는다!
1. DOM프로퍼티
DOM 프로퍼티의 종류는 엄청나게 많지만 이런 내장 프로퍼티만으로 충분하지 않은 경우 자신만의 프로퍼티를 만들 수도 있다.
<<document.body에 새로운 프로퍼티를 만들기>>
document.body.myData = {
name: 'Caesar',
title: 'Imperator'
};
alert(document.body.myData.title); // Imperator
DOM 프로퍼티는 일반 자바스립트 객체처럼 행동하므로 아래와 같은 특징을 보인다.
- 어떤 값이든 가질 수 있다.
- 대·소문자를 가린다. elem.nodeType는 동작하지만 elem.NoDeTyPe는 동작하지 않는다.
2. HTML 속성
HTML에서 태그는 복수의 속성을 가질 수 있다. 브라우저는 HTML을 파싱해 DOM 객체를 만들 때 HTML 표준속성을 인식하고, 이 표준 속성을 사용해 DOM프로퍼티를 만든다.
따라서 요소가 id같은 표준 속성으로만 구성되어 있다면, 이에 해당하는 프로퍼티가 자연스레 만들어진다.
하지만 표준이 아닌 속성일 때는 상황이 달라진다.
<body id="test" something="non-standard">
<script>
alert(document.body.id); // test
// 비표준 속성은 프로퍼티로 전환되지 않는다.
alert(document.body.something); // undefined
</script>
</body>
한 요소에선 표준인 속성이 다른 요소에선 표준이 아닐 수 있다는 점에도 주의해야 한다. "type"은 <input> 에선 표준이지만 <body>에선 아니다.
<body id="body" type="...">
<input id="input" type="text">
<script>
alert(input.type); // text
alert(body.type); // type은 body의 표준 속성이 아니므로 DOM 프로퍼티가 생성되지 않아 undefined가 출력
</script>
</body>
**표준 속성이 아닌 경우, 이에 매핑하는 DOM프로퍼티가 생성되지 않지만, 비표준 속성으로 접근하는 방법**
- elem.hasAttribute(name) – 속성 존재 여부 확인
- elem.getAttribute(name) – 속성값을 가져옴
- elem.setAttribute(name, value) – 속성값을 변경함
- elem.removeAttribute(name) – 속성값을 지움
3. 프로퍼티-속성 동기화
표준 속성이 변하면 대응하는 프로퍼티는 자동으로 갱신된다. 몇몇 경우를 제외하고 프로퍼티가 변하면 속성 역시 마찬가지로 갱신된다.
<input>
<script>
let input = document.querySelector('input');
// 속성 추가 => 프로퍼티 갱신
input.setAttribute('id', 'id');
alert(input.id); // id (갱신)
// 프로퍼티 변경 => 속성 갱신
input.id = 'newId';
alert(input.getAttribute('id')); // newId (갱신)
</script>
4. DOM프로퍼티 값의 타입
DOM 프로퍼티는 항상 문자열이 아니다. 체크 박스에 사용되는 input.checked 프로퍼티의 경우 불린 값을 가진다.
<input id="input" type="checkbox" checked> checkbox
<script>
alert(input.getAttribute('checked')); // 속성 값: 빈 문자열
alert(input.checked); // 프로퍼티 값: true
</script>
style 속성의 경우 문자열이지만, style 프로퍼티는 객체이다.
<div id="div" style="color:red;font-size:120%">Hello</div>
<script>
// string
alert(div.getAttribute('style')); // color:red;font-size:120%
// object
alert(div.style); // [object CSSStyleDeclaration]
alert(div.style.color); // red
</script>
5. 비표준 속성, dataset
HTML을 작성할 때 우리는 대부분 표준 속성을 사용한다. 하지만 표준이 아닌 속성도 존재한다.
비표준 속성은 사용자가 직접 지정한 데이터를 HTML에서 자바스크립트로 넘기고 싶은 경우나 자바스크립트를 사용해 조작할 HTML 요소를 표시하기 위해 사용할 수 있다.
<!-- 이름(name) 정보를 보여주는 div라고 표시 -->
<div show-info="name"></div>
<!-- 나이(age) 정보를 보여주는 div라고 표시 -->
<div show-info="age"></div>
<script>
// 표시한 요소를 찾고, 그 자리에 원하는 정보를 보여주는 코드
let user = {
name: "Pete",
age: 25
};
for(let div of document.querySelectorAll('[show-info]')) {
// 원하는 정보를 필드 값에 입력해 줌
let field = div.getAttribute('show-info');
div.innerHTML = user[field]; // Pete가 'name'에, 25가 'age'에 삽입됨
}
</script>
비표준 속성은 요소에 스타일을 적용할 때 사용되기도 한다.
<style>
/* 스타일이 커스텀 속성 'order-state'에 따라 변합니다. */
.order[order-state="new"] {
color: green;
}
.order[order-state="pending"] {
color: blue;
}
.order[order-state="canceled"] {
color: red;
}
</style>
<div class="order" order-state="new">
A new order.
</div>
<div class="order" order-state="pending">
A pending order.
</div>
<div class="order" order-state="canceled">
A canceled order.
</div>
이렇게 커스텀 속성을 사용하는 게 .order-state-new, .order-state-pending, order-state-canceled같은 클래스를 사용하는 것보다 왜 선호될까?
--> 속성은 클래스보다 다루기 편리하기 때문이다.
// 새 클래스를 추가하거나 지우는 것보다 더 쉽게 상태(state)를 바꿀 수 있다.
div.setAttribute('order-state', 'canceled');
물론 커스텀 속성에도 문제가 발생할 수 있다.
비표준 속성을 사용해 코드를 작성했는데 나중에 그 속성이 표준으로 등록되게 되면 문제가 발생하기 때문!!
이런 충돌을 방지하기 위한 속성인 data-*가 있다.
’data-'로 시작하는 속성 전체는 개발자가 용도에 맞게 사용하도록 별도로 예약된다. dataset 프로퍼티를 사용하면 이 속성에 접근할 수 있다.
<body data-about="Elephants">
<script>
alert(document.body.dataset.about); // Elephants
</script>
'Front-end > JavaScript' 카테고리의 다른 글
[JavaScript] 브라우저 창 사이즈와 스크롤 (0) | 2022.06.20 |
---|---|
[JavaScript] 스타일과 클래스 (0) | 2022.06.19 |
[JavaScript] 주요 노드 프로퍼티 (0) | 2022.06.19 |
[JavaScript] getElement, querySelector (0) | 2022.06.19 |
[JavaScript] DOM트리 (0) | 2022.06.18 |