// 스타일 다루기
const today = document.querySelector('#today');
const tomorrow = document.querySelector('#tomorrow');
// style 프로퍼티
today.children[0].style.textDecoration = 'line-through';
today.children[0].style.backgroundColor = '#DDDDDD';
스타일 프로퍼티를 통해서 css속성을 다룰 때 여러 단어를 이어서 만든 속성은 camel표기법을 이용해야한다. style 프로퍼티를 이용하면 태그의 스타일 속성에 직접적으로 우리가 표기한 속성이 포함된다. 이렇게 되면 스타일 우선순위가 높아져버리기도 하고, 같은 스타일을 다른 여러 태그에 적용해야 할 때는, 비슷한 코드를 불필요하게 많이 작성해야 하기도 한다.
때문에 의도된 상황이 아니라면 일반적으로 자바스크립트를 사용해서 스타일 프로퍼티를 입힐 때, 태그에 클래스를 변경하는 방식이 좀 더 권장되는 방식이다. 자바스크립트로 HTML 클래스를 다루는 방식에는 두 가지가 있다.
.done {
opacity: 0.5;
text-decoration: line-through;
}
// elem.className
today.children[1].className = 'done';
먼저 style sheet에 스타일을 작성해두고, 이렇게 적용하면 된다. 그러나 이렇게 적용하게 되면 한 가지 문제점이 생긴다. 바로 class 속성값 전체가 바뀌는 것이다. 상황에 따라서 기존에 사용하던 class를 두고 새로운 class를 추가하고 싶을 수가 있는데, 그럴 때는 className보다 classList property를 활용하면 된다.
console.log(today.classList);
console.log(today.children[1].classList);
const item = tomorrow.children[1];
item.classList.add('done');
item.classList.add('done', 'other');
// 여러 개의 클래스를 넣고 싶을 때는 쉼표로 구분하며 여러 개의 파라미터를 넣으면 된다. 만약 똑같은 이름의 클래스를 중복해서 추가하더라도 코드를 실행해보면 결국 하나만 추가된다.
item.classList.remove('done');
//remove는 클래스를 제거하는 것이니까 파라미터로 전달하는 클래스를 제거한다. add와 마찬가지로 여러개의 파라미터를 전달한만큼 삭제할 수 있다.
item.classList.toggle('done');
// 있으면 제거하고, 없으면 추가하는 method이다. toggle은 여러 개의 파라미터를 전달한다고 해서 여러 개의 클래스를 토글하지는 않는다. toggle의 두 번째 파라미터에 특별한 기능이 있기 때문이다. boolean형태의 값을 전달받아서 만약 true를 전달하게 되면 add의 기능만 하고, false를 전달하면 remove의 기능만 하도록 토글의 기능을 강제할 수 있다. 어쨌든 toggle 메소드는 클래스 한 개만 사용한다.
이는 class의 속성값을 유사배열로 다루는 property인데, classList활용하면 속성을 하나씩 다룰 수 있을뿐만 아니라 class를 좀 더 편하게 다룰 수 있는 add, remove, toggle 이라는 method 또한 사용할 수 있다.
<!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;
}
위 코드의 b 태그들의 field 속성과 button 태그들의 status 라는 속성은 비표준 속성이다. 또한 [속성이름] 처럼 css에서 대괄호를 이용하면 대괄호 안에 있는 속성이름을 가진 태그들을 선택할 수 있고 [속성이름 = "값"] 처럼 작성하면, 좀 더 구체적으로 속성이름에 해당 값을 가진 태그들을 선택할 수도 있다.
const fields = document.querySelectorAll('[field]');
console.log(fields);
값을 표시할 태그를 구분할 때 활용
비표준 속성은 객체 형태의 데이터가 있을 때, 각 프로퍼티 값들이 들어갈 태그를 구분하는데 활용할 수도 있다.
스타일이나 데이터 변경에 활용
getAttribute 메소드를 활용해서 속성값을 가져오고, setAttribute 메소드를 활용해서 속성값을 설정해주는 원리로 이벤트를 통해 실시간으로 스타일을 변경하거나 데이터를 변경하는데 활용할 수 있다. 때로는 class를 다루는 것보다 setAttribute로 비표준 속성을 변경하는게 스타일을 다루기에 오히려 편리한 경우도 있다.
다양한 방식으로 활용되는 비표준 속성에는 한 가지 문제점이 있는데, 바로 비표준 속성을 사용해 코드를 작성했을 때 시간이 지나서 나중에 그 속성이 표준으로 등록되면 문제가 발생할 수 있다는 것이다. HTML은 아직까지도 개발자들의 요구를 반영하기 위해 계속해서 발전하는 언어이기에 이런 경우 예기치 못한 부작용이 발생될 수 있는 것이다.
그래서 비표준 속성을 사용하기 위해 미리 약속된 방식이 존재하는데, 바로 data-* 속성이다.
data- 로 시작하는 속성은 모두 dataset이라는 프로퍼티에 저장되는데, 예를 들어 data-status라는 속성이 있다면 element.dataset.status라는 프로퍼티에 접근해서 그 값을 가져올 수 있는 것이다.
비표준 속성을 활용하는 것은 개발자의 선택적인 부분이기에 다양한 상황들을 고려해서, 만약 비표준 속성을 활용해야 한다면 data-* 형태와 dataset 프로퍼티를 사용하는 것이 조금 더 안전하다.