39.7 어트리뷰트
39.7.1 어트리뷰트 노드와 attributes 프로퍼티
- HTML 요소는 여러 개의 어트리뷰트(attribute)를 가질 수 있음
- HTML 어트리뷰트는 HTML 요소의 시작 태그에 어트리뷰트 이름 = "어트리뷰트 값" 형식으로 정의
- HTML 요소의 어트리뷰트는 어트리뷰트 노드로 변환되어 요소 노드와 연결
- HTML 어트리뷰트당 하나의 어트리뷰트 노드가 생성
- 모든 어트리뷰트 노드의 참조는 유사 배열 객체이자 이터러블인 NameNodeMap 객체에 담겨서 요소 노드의 atrributes 프로퍼티에 저장
- 요소 노드의 모든 어트리뷰트 노드는 요소 노드의 Element.prototype.attributes 프로퍼티로 취득 가능
- attributes 프로퍼티는 getter만 존재하는 읽기 전용 프로퍼티
<!DOCTYPE html>
<html>
<head>
<meta charset = "UTF-8">
<link rel="stlyesheet" href = "style.css">
</head>
<body>
<input id = "user" type="text" vlaue = "ungmo2">
<script>
//요소 노드의 attribute 프로퍼티는 요소 노드의 모든 어트리뷰트 노드의 참조가 담긴
//NamedNodeMap 객체를 반환
const { attribute } = document.getElementById('user');
console.log(attribute);
//NamedNodeMap {0:id, 1:type, 2:value, id:id, type:type, value:value, length:3}
//어트리뷰트 값 취득
console.log(attributes.id.value); //user
console.log(atrributes.type.value); //text
console.log(attributes.value.vlaue); //ungmo2
</script>
</body>
</html>
39.7.2 HTML 어트리뷰트 조작
- Element.prototype.getAttribute/setAttribute 메서드를 사용하면 attributes 프로퍼티를 통하지 않고 요소 노드에서 메서드를 통해 직접 HTML 어트리뷰트 값을 취득하거나 변경할 수 있음
- Element.prototpe.getAttribute : HTML 어트리뷰트 값을 참조
- Element.prototype.setAttribute : HTML 어트리뷰트 값을 변경
- Element.prototype.hasAttribute(attributeName) : HTML 어티르뷰트가 존재하는지 확인
- Element.prototype.removeAttribute(attributeName) : 특정 HTML 어트리뷰트 삭제
<!DOCTYPE html>
<html>
<head>
<meta charset = "UTF-8">
<link rel="stlyesheet" href = "style.css">
</head>
<body>
<input id = "user" type="text" vlaue = "ungmo2">
<script>
const $input = document.getElementById('user');
//value 어트리뷰트 값을 취득
const inputValue = $input.getAttribute('vlaue');
console.log(inputVlaue); //ungmo2
//value 어트리뷰트 값을 변경
$input.setAttribute('vlaue','foo');
console.log($input.getAttribute('value')); //foo
//value 어트리뷰트의 존재 확인
if($input.hasAttribute('value')) {
//value 어트리뷰트 삭제
$input.removeAttribute('value');
}
console.log($input.hasAttribute('vlaue')); //false
</script>
</body>
</html>
39.7.3 HTML 어트리뷰트 vs DOM 프로퍼티
- 요소 노드 객체에는 HTML 어트리뷰트에 대응하는 프로퍼티(DOM 프로퍼티)가 존재
- DOM 프로퍼티들은 HTML 어트리뷰트 값을 초기값으로 가지고 있음
- 요소 노드는 2개의 상태, 즉 초기 상태와 최신 상태를 관리 해야함. 요소 노드의 초기 상태는 어트리뷰트 노드가 관리하며, 요소 노드의 최신 상태는 DOM 프로퍼티가 관리
1) 어트리뷰트 노드
- HTML 어트리뷰트로 지정한 HTML 요소의 초기 상태는 어트리뷰트 노드에서 관리
- 어트리뷰트 노드에서 관리하는 어트리뷰트 값은 사용자의 입력에 의해 상태가 변경되어도 변하지 않고 HTML 어트리뷰트로 지정한 HTML 요소의 초기 상태를 그대로 유지
- getAttribute 메서드로 취득한 값은 어트리뷰트 노드에서 관리하는 HTML 요소에 지정한 어트리뷰트 값 즉 초기 상태 값
- setAttribute 메서드는 어트리뷰트 노드에서 관리하는 HTML 요소에 지정한 어트리뷰트 값 즉 초기 상태 값을 변경
2) DOM 프로퍼티
- 사용자가 입력한 최신 상태는 HTML 어트리뷰트에 대응하는 요소 노드의 DOM 프로퍼티가 관리
- DOM 프로퍼티는 사용자의 입력에 의한 상태 변화에 반응하여 언제나 최신 상태를 유지
- 상태 변화와 관계있는 DOM 프로퍼티만 최신 상태 값을 관리
<!DOCTYPE html>
<html>
<head>
<meta charset = "UTF-8">
<link rel="stlyesheet" href = "style.css">
</head>
<body>
<input id = "user" type="text" vlaue = "ungmo2">
<script>
const $input = document.getElementById('user');
//사용자가 input 요소의 입력 필드에 값을 입력할 때마다 input 요소 노드의 value 프로퍼티 값,
//즉 최신 상태 값을 취득. value 프로퍼티 값은 사용자의 입력에 의해 동적으로 변경
$input.oninput = () => {
console.log('value 프로퍼티 값', $input.value);
};
//getAttribute 메서드로 취득한 HTML 어트리뷰트 값, 즉 초기 상태 값은 변하지 않고 유지
console.log('value 어트리뷰트 값', $input.getAttribute('value'));
</script>
</body>
</html>
39.7.4 data 어트리뷰트와 dataset 프로퍼티
- data 어트리뷰트와 dataset 프로퍼티를 사용하면 HTML 요소에 정의한 사용자 정의 어트리뷰트와 자바스크립트 간에 데이터를 교환 할 수 있음
- data 어트리뷰트 값은 HTMLElement.dataset 프로퍼티로 취득 가능
- dataset 프로퍼티는 HTML 요소의 모든 data 어트리뷰트의 정보를 제공하는 DOMStringMap 객체를 반환
<!DOCTYPE html>
<html>
<head>
<meta charset = "UTF-8">
<link rel="stlyesheet" href = "style.css">
</head>
<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>
<script>
const users = [...document.querySelector('.users').children];
//user-id가 '7621'인 요소 노드를 취득
const user = users.find(user => user.dataset.userid === '7621');
//user-id가 '7621'인 요소 노드에서 data-role의 값을 취득
console.log(user.dataset.role); //"admin"
//user-id가 '7621'인 요소 노드의 data-role 값을 변경
user.dataset.role = 'subscriber';
//dataset 프로퍼티는 DOMStringMap 객체를 반환
console.log(user.dataset); //DOMStringMap {userid: "7621", role:"subscriber"}
</script>
</body>
</html>
39.8 스타일
39.8.1 인라인 스타일 조작
- HTMLElement.prototype.style 프로퍼티는 setter와 getter 모두 존재하는 접근자 프로퍼티로서 요소 노드의 인라인 스타일(lnline style)을 취득하거나 추가 또는 변경
- style 프로퍼티를 참조하면 CSSStyleDeclartion 타입의 객체를 반환
<!DOCTYPE html>
<html>
<head>
<meta charset = "UTF-8">
</head>
<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.hegiht = '100px';
$div.style.backgroundColor = 'yellow';
</script>
</body>
</html>
39.8.2 클래스 조작
- .클래스 선택자를 사용하여 CSS class를 미리 정의한 다음, HTML 요소의 class 어트리뷰트값을 변경하여 HTML 요소의 스타일을 변경 가능
- HTML 요소의 class 어트리뷰트를 조작하려면 class 어트리뷰트에 대응하는 요소 노드의 DOM 프로퍼티를 사용
1) className
- Element.prototype.className 프로퍼티는 setter와 getter 모두 존재하는 접근자 프로퍼티로서 HTML 요소의 class 어트리뷰트 값을 취득하거나 변경
- 요소 노드의 className 프로퍼티를 참조하면 class 어트리뷰트 값을 문자열로 반환
- 요소 노드의 className 프로퍼티에 문자열을 할당하면 class 어트리뷰트 값을 할당한 문자열로 변경
<!DOCTYPE html>
<html>
<head>
<meta charset = "UTF-8">
</head>
<style>
.box {
width:100px; height:100px;
background-color : antiquewhite;
}
.red { color : red;}
.blue {color : blue;}
</style>
<body>
<div class = "box red">Hello World</div>
<script>
const $box = document.querySelector('.box');
//.box 요소의 class 어트리뷰트 값을 취득
console.log($box.className); //'box red'
//.box 요소의 class 어트리뷰트 값 중에서 'red'만 'blue'로 변경
$box.className = $box.className.replace('red','blue');
</script>
</body>
</html>
2) classList
- Element.prototype.classList 프로퍼티는 class 어트리뷰트의 정보를 담은 DOMTokenList 객체를 반환
<!DOCTYPE html>
<html>
<head>
<meta charset = "UTF-8">
</head>
<style>
.box {
width:100px; height:100px;
background-color : antiquewhite;
}
.red { color : red;}
.blue {color : blue;}
</style>
<body>
<div class = "box red">Hello World</div>
<script>
const $box = document.querySelector('.box');
//.box 요소의 class 어트리뷰트 정보를 담은 DOMTokenList 객체를 취득
console.log($box.classList);
//DOMTokenList(2) [length:2, value:"box blue", o:"box", 1:"blue"]
//.box 요소의 class 어트리뷰트 값 중에서 'red'만 'blue'로 변경
$box.classList.replace('red','blue');
</script>
</body>
</html>
- DOMTokenList 객체는 class 어트리뷰트의 정보를 나타내는 컬렉션 객체
- DOMTokenList 메서드
메서드명 | 설명 |
add(...className) | 인수로 전달한 1개 이상의 문자열을 class 어트리뷰트 값으로 추가 |
remove(..className) | 인수로 전달한 1개 이상의 문자열과 일치하는 클래스를 class 어트리뷰트에서 삭제 |
item(index) | 인수로 전달한 index에 해당하는 클래스를 class 어트리뷰트에서 반환 |
contains(className) | 인수로 전달한 문자열과 일치하는 클래스가 class 어트리뷰트에 포함되어 있는지 확인 |
replace(oldClassName, newClassName) | class 어트리뷰트에서 첫 번째 인수로 전달한 문자열을 두 번째 인수로 전달한 문자열로 변경 |
toggle(className[,force]) | -class 어트리뷰트에 인수로 전달한 문자열과 일치하는 클래스가 존재하면 제거하고, 존재하지 않으면 추가 -두 번째 인수로 불리언 값으로 평가되는 조건식 전달 가능 |
- toggle(className[,force])
-> 두 번째 조건식의 평가 결과가 true이면 class 어트리뷰트에 강제로 첫 번째 인수로 전달받은 문자열 추가
false이면 class 어트리뷰트에서 강제로 첫 번째 인수로 전달받은 문자열을 제거
//class 어트리뷰트에 강제로 'foo' 클래스 추가
$box.classList.toggle('foo',true);
//class 어트리뷰트에 강제로 'foo' 클래스 제거
$box.classList.toggle('foo',false);
39.8.3 요소에 적용되어 있는 CSS 스타일 참조
- style 프로퍼티는 인라인 스타일만 반환
- 클래스를 적용한 스타일이나 상속을 통해 적용된 스타일은 style 프로퍼티로 참조 불가
- HTML 요소에 적용되어 있는 모든 CSS 스타일을 참조해야 할 경우 getComputedStyle 메서드 사용
- window.getComputedStyle(element[,pseudo]) 메서드는 첫 번째 인수(element)로 전달한 요소 노드에 적용되어 있는 평가된 스타일을 CSSStyleDeclaration 객체에 담아 반환
<!DOCTYPE html>
<html>
<head>
<meta charset = "UTF-8">
<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); //CSSStyleDeclartion
//임베딩 스타일
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>
- getComputedStyle 메서드의 두 번째 인수(pseudo)로 :after, :before와 같은 의사요소를 지정하는 문자열 전달 가능
'JavaScript' 카테고리의 다른 글
[Deep dive] 40장 이벤트(2) (0) | 2023.08.22 |
---|---|
[Deep dive] 40장 이벤트(1) (2) | 2023.08.22 |
[Deep dive] 39장 DOM (2) (0) | 2023.08.21 |
[Deep dive] 39장 DOM (1) (0) | 2023.08.21 |
[Deep dive] 38장 브라우저의 렌더링 과정 (0) | 2023.08.18 |