모던 JavaScript 튜토리얼 파트 2. 브라우저: 문서, 이벤트, 인터페이스를 읽고 정리, 기록
요소에 스타일을 적용할 수 있는 방법
- CSS에 클래스를 만들고, 요소에 <div class=”…”> 처럼 클래스 추가하기
- <div style=”…”> 처럼 프로퍼티를 style에 바로 쓰기
자바스크립트를 사용하면 클래스와 style 프로퍼티 둘 다 수정할 수 있다.
style은 클래스를 ‘다룰 수 없을 때’만 사용해야 한다.
→ 유연성이 확보되어 유지보수가 쉬워진다.
style은 자바스크립트를 사용해 요소의 좌표를 동적으로 계산하고, 계산한 좌표를 설정해주고자 할 때 사용하면 좋다.
let top = /* 복잡한 계산식 */;
let left = /* 복잡한 계산식 */;
elem.style.left = left; // 예시: '123px', 런타임으로 좌표를 계산할 수 있다.
elem.style.top = top; // 예시: '456px'
className과 classList
className 프로퍼티가 도입된 배경
- 오래전 자바스크립트에서는 class 같은 예약어는 객체의 프로퍼티가 될 수 없었기 때문에 (현재는 가능), elem.class를 사용하는 것이 불가능했다. 따라서 elem.className 을 사용
- className = class 속성에 대응
- className 을 바꾸면 class 문자열 전체가 바뀐다.
<body class="main page">
<script>
alert(document.body.className); // main page
</script>
</body>
클래스 여러 개를 조작하고 싶을 때 elem.classList 를 사용한다.
- 이터러블 객체이기 때문에 for..of 를 사용할 수 있다.
elem.classList 엔 클래스 하나만을 조작하게 해주는 메서드 add/remove/toggle 이 구현되어 있다.
<body class="main page">
<script>
// 클래스 추가
document.body.classList.add('article');
alert(document.body.className); // main page article
</script>
</body>
elem.classList.add/remove("class")
- class를 추가하거나 제거
elem.classList.toggle("class")
- class가 존재할 경우 class를 제거하고, 그렇지 않은 경우엔 추가
elem.classList.contains("class")
- class 존재 여부에 따라 true/false를 반환
요소의 스타일
elem.style 은 속성 style에 쓰인 값에 대응되는 객체이다.
여러 단어를 이어 만든 프로퍼티는 카멜 표기법으로 이름 짓는다.
background-color => elem.style.backgroundColor
z-index => elem.style.zIndex
border-left-width => elem.style.borderLeftWidth
특정 브라우저 전용 프로퍼티 역시 카멜 표기법을 사용한다.
대시(-) 는 대문자를 의미한다. (와우)
-moz-border-radius, -webkit-border-radius
button.style.MozBorderRadius = '5px';
button.style.WebkitBorderRadius = '5px';
style 프로퍼티 재지정하기
style 프로퍼티에 값을 할당했다가 이를 제거해야할 경우
elem.style.display = “none”
- style.display를 설정하지 않았던 것처럼 돌리고 싶다.
- delete elem.style.display 를 사용해 프로퍼티를 삭제하는 대신, elem.style.display = “” 같이 빈 문자열을 할당해주어야 한다.
- style.display에 빈 문자열을 할당하면 브라우저는 마치 처음부터 style.display 프로퍼티가 없었던 것처럼 CSS 클래스와 브라우저 내장 스타일을 페이지에 적용한다.
// 예시를 실행하면 페이지의 <body>가 깜빡인다.
document.body.style.display = "none"; // hide
// 1초 후 다시 원래 상태로 돌아온다.
setTimeout(() => document.body.style.display = "", 1000);
style.cssText로 완전히 다시 쓰기
개별 스타일 프로퍼티를 적용할 때는 보통 style.*를 사용한다.
하지만 div.style 은 객체이고 읽기 전용이기 때문에 div.style="color: red; width: 100px"같은 방식으론 전체 스타일을 설정할 수 없다.
문자열을 사용해 전체 스타일을 설정하려면 프로퍼티 style.cssText를 사용해야 한다.
- 이전 스타일이 지워질 위험이 있기 때문에 잘 쓰이지 않음.
- div.setAttribute(’style’, ‘color: red’) 를 사용해 속성을 설정해도 style.cssText와 동일하게 완전히 다시 쓰인다.
<div id="div">버튼</div>
<script>
// cssText를 사용하면 'important' 같은 규칙도 설정할 수 있다.
div.style.cssText=`color: red !important;
background-color: yellow;
width: 100px;
text-align: center;
`;
alert(div.style.cssText);
</script>
단위에 주의하기
자바스크립트를 사용해 스타일 값을 설정할 때는 단위를 붙여줘야 한다.
10px이 아닌 10을 설정하면 제대로 동작하지 않는다.
getComputedStyle로 계산된 스타일 얻기
style 프로퍼티는 “style” 속성의 값을 읽을 때만 사용할 수 있기 때문에 style 프로퍼티만으로는 CSS 종속(CSS cascade) 값을 다루지 못한다.
스타일을 읽는 방법: getComputedStyle
- getComputedStyle을 호출하면 elem.style 같이 스타일 정보가 들어있는 객체가 반환되는데, elem.style과 달리 전체 CSS 클래스 정보도 함께 담긴다.
// element: 값을 읽을 요소
// pseudo : ::before같이 의사 요소(pseudo-element)가 필요한 경우 명시해줌.
// 빈 문자열을 넘겨주거나 아무런 값을 입력하지 않은 경우 요소 자체를 의미함
getComputedStyle(element, [pseudo])
<head>
<style> body { color: red; margin: 5px } </style>
</head>
<body>
<script>
let computedStyle = getComputedStyle(document.body);
// 이제 마진과 색 정보를 얻을 수 있다.
alert( computedStyle.marginTop ); // 5px
alert( computedStyle.color ); // rgb(255, 0, 0)
</script>
</body>
계산 값과 결정 값
CSS에는 속성과 관련된 두 가지 개념이 있다.
- 계산 값(computed style value)
- CSS 규칙과 CSS 상속이 모두 적용된 후의 값을 의미
- 값의 형태: height:1em or font-size:125%
- 결정 값(resolved style value)
- 요소에 최종적으로 적용되는 값
- 계산 값에서 사용한 1em나 125%은 상대 단위를 사용하는 상댓값인데, 브라우저는 계산 값을 받아 단위를 전환해 height:20px나 font-size:16px같이 고정 단위를 사용하는 값(절댓값)으로 값을 변환한다.
- 기하 관련 프로퍼티의 결정 값에는 width:50.5px같이 소수점 단위가 있을 수 있다.
getComputedStyle은 계산 값을 얻기 위해서 만들어진 아주 오래된 메서드다.
계산 값보다는 결정 값을 사용하는 게 훨씬 편리하기 때문에 표준이 개정되었다.
따라서 지금은 getComputedStyle을 호출하면 프로퍼티의 결정 값이 반환된다.
기하 프로퍼티의 경우 주로 px가 단위로 사용된다.
getComputedStyle엔 프로퍼티 전체 이름이 필요하다.
getComputedStyle을 사용할 때는 paddingLeft, marginTop, borderTopWidth같이 프로퍼티 이름 전체를 정확히 알고 있어야 한다. 그렇지 않으면 원하는 값을 얻을 수 없는 경우가 생긴다.
- paddingLeft나 paddingTop엔 값이 지정되어있는데 getComputedStyle(elem).padding을 사용해 값을 얻으려 하는 경우
- 어떤 값? 이런 상황에 적용할만한 표준은 아직 제정되어있지 않다.
→ 따라서 브라우저마다 동작 방식이 다르다.
Chrome 같은 몇몇 브라우저: 아래 예시와 같이 10px을 출력한다. Firefox: 빈 문자열을 출력한다.
<style>
body {
margin: 10px;
}
</style>
<script>
let style = getComputedStyle(document.body);
alert(style.margin); // Firefox에선 빈 문자열이 출력됩니다.
</script>
:visited 링크 관련 스타일은 숨겨져 있다.
방문한 적이 있는 링크엔 :visited라는 CSS 의사 클래스를 사용해 색을 입힐 수 있다.
하지만 getComputedStyle을 사용해서 이 색을 얻을 수 없다.
→ 색을 얻을 수 있도록 하면 임의의 페이지에서 사용자가 해당 링크를 방문했는지 아닌지를 getComputedStyle을 사용해 알아낼 수 있기 때문이다.
- 자바스크립트로는 :visited에 적용된 스타일을 얻지 못한다.
- 여기에 더하여 CSS에는 :visited에 기하학적 변화를 가져오는 스타일을 적용하는 것을 금지하는 제약도 있다.
- 이런 제약들은 악의를 가진 페이지가 사용자가 링크를 방문했는지 여부를 테스트 하고, 방문 여부에 따라 사생활을 침해할 만한 어떠한 것도 하지 못하도록 하려고 만들어졌다.
'FE' 카테고리의 다른 글
1.10 브라우저 창 사이즈와 스크롤 (1) | 2024.11.19 |
---|---|
1.9 요소 사이즈와 스크롤 (0) | 2024.11.17 |
1.7 문서 수정하기 (4) | 2024.11.15 |
1.6 속성과 프로퍼티 (0) | 2024.11.14 |
1.5 주요 노드 프로퍼티 (2) (1) | 2024.11.13 |