[바닐라 JS로 크롬 앱 만들기] # 3.6-3.8 CSS in Javascript

Gata·2023년 11월 23일
post-thumbnail

오늘의 핵심: toggle 최고👍🏻

마우스로 h1를 클릭했을 때 h1의 색을 blue -> tomato -> blue -> tomato 순으로 바꿔보는 코드를 짜보려고 한다.

const h1 = document.querySelector("div.hello:first-child h1"); //element 선택

function handleTitleClick() {
    if(h1.style.color === "blue") {
        h1.style.color = "tomato";
    } else {
        h1.style.color = "blue";
    } 
}

h1.addEventListener("click", handleTitleClick);

<해석>

h1.style.color가 "blue"면 (true)
h1.style.color를 "tomato"로 바꾸고,
h1.style.color가 "blue"가 아니면 (false)
h1.style.color를 "blue"로 바꾼다.

위의 코드보다 더 깔끔한 코드가 있다.
h1.style.color를 이렇게 많이 호출 할 때는 따로 변수에 담는 것이 좋다.


📌변수에 담기

const h1 = document.querySelector("div.hello:first-child h1"); //element 선택

function handleTitleClick() {
    const currentColor = h1.style.color;
    let newColor;
    if (currentColor === "blue") {
        newColor = "tomato";
    } else {
        newColor = "blue";
    }
    h1.style.color = newColor;
}

h1.addEventListener("click", handleTitleClick);

<해석>

  1. currentColor는 getter로써, 현재 color값을 담는 역할을 한다. 현재 색은 "blue"이고 변하지 않는 값이기 때문에 const로 선언한다.

  2. newColor는 setter로써, 변수에 대입된 색상 값을 최종적으로 h1.style.color에 할당하는 역할을 한다. 의미론적으로 값이 변경될 수 있음을 염두해 두기 위해 let으로 선언한다.

  3. 프로그래밍에서 '=' 표시는 오른쪽에 있는 값을 왼쪽에 대입한다는 뜻이다.

  4. 함수 내에서 선언된 변수는 함수 밖에서는 존재하지 않는다. 그렇기 때문에 const currentColor로 변수 선언을 하더라도, 함수가 호출될 때마다 새로운 값을 받을 수 있다.


이를 토대로 코드를 순차적으로 이해하면,
1) element 인식
2) click event 발생 및 함수 실행
3) currentColor 변수 선언 후, h1.style.color 값 담기 (getter)
4) newColor 변수 선언
5) currentColor 현재 값 확인
6) 조건에 따라 newColor에 "tomato" or "blue" 값 대입
7) 마지막으로 h1.style.color에 newColor값 대입 (setter)


코드 차이 알기

h1.style.color = newColor
newColor = h1.style.color

첫번째 코드는 h1의 색을 newColor 값으로 바꾼다는 뜻이고, 두번째 코드는 h1의 색을 newColor 변수에 저장한다는 뜻이다.


functions

📌className

  • className의 단점
    html에서 class를 별도로 설정해줘도 class명을 지키지 못한다.
const h1 = document.querySelector("div.hello:first-child h1");

function handleTitleClick () {
    const clickedClass = "clicked";

    if (h1.className === clickedClass) {
        h1.className = "";
    } else {
        h1.className = clickedClass;
    }

h1.addEventListener("click",handleTitleClick);
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <link rel="stylesheet" href="style.css">
    <title>Momentum App</title>
</head>
<body>
    <div class="hello">
        <h1 class="sexy-font">Click me!</h1>
    </div>
    <script src="app.js"></script>
</body>
</html>
  • <클릭 안했을 때>

  • <클릭 했을 때>

결론: className을 쓰면 html에서 class명을 따로 추가해줬을 때 브라우저에 적용이 안된다.

그래서 다음으로 사용해 볼 방법은 classList이다.


📌classList

classList의 function

  • constains: 우리가 명시한 class가 HTML element의 class에 포함되어 있는지 말해준다.

    clickedClass가 h1의 classList에 포함되어 있다면 clickedClass를 제거한다.
    만약 clickedClass가 h1의 classList에 포함되어 있지 않다면, clickedClass를 추가한다.

// 📌classList

if (h1.classList.contains(clickedClass)) {
        h1.classList.remove(clickedClass);
    } else {
        h1.classList.add(clickedClass);
    }

📌toggle

toggle은 h1의 classList에 clicked class가 이미 있는지 확인해서 class가 존재하면 clicked을 제거해주고, class가 존재하지 않으면 clicked을 classList에 추가한다.

toggle의 예시

  • 버튼을 누르면 불빛이 켜지고, 다시 한번 누르면 꺼진다.
  • 스마트폰의 스크린을 탭하면 잠기고, 다시 한번 누르면 켜진다.
// 📌toggle

h1.classList.toggle("clicked");

className, classList, toggle 코드 한번에 비교해보기

세 코드블럭은 모두 같은 결과를 낸다.

// 📌className

if (h1.className === clickedClass) {
        h1.className = "";
    } else {
        h1.className = clickedClass;
    }
// 📌classList

if (h1.classList.contains(clickedClass)) {
        h1.classList.remove(clickedClass);
    } else {
        h1.classList.add(clickedClass);
    }
// 📌toggle

h1.classList.toggle("clicked");

결론: toggle을 쓰는게 제일 간편하다.

profile
개발은 즐거워🪇

0개의 댓글