최근 웹사이트에서 눈의 피로(?)를 줄이기 위한 다크 모드를 쉽게 볼수 있다. 이를 자바스크립트를 통해 구현해보자.
아이콘을 클릭함에 따라 배경화면과 글자색이 변경되도록 구현해야합니다. 이를 구현해주는 자바스크립트 기능을 알아보겠습니다.
1. Toggle
자바스크립트에서는 toggle 이라는 특수한 메서드를 제공합니다. 스위치를 켯다 껏다 반복하는 이미지로 이해하면 훨씬 와닿을겁니다.
직관적으로 보면 그냥 클릭 한번으로 쉽게 구현이 될 것 같지만, toggle을 이용하지 않는다면, 과정 자체는 조금 길어지게 됩니다.
body{
background-color: #f3f3fe;;
color: #000;;
}
body.dark-theme{
background-color: #000; /* 검정색 */
color: #f3f3fe; /* 흰 계통 색*/
}
// 메뉴 버튼을 html 에서 클릭할 시,
$menu.addEventListener("click", () => {
if(body.classList.contains("dark-theme")){
body.classList.remove("dark-theme");
}else{
body.classList.add("dark-theme");
})
위 간단한 코드를 살펴보자면, 미리 CSS 에 지정해둔 dark-theme 를 body 에 적용한다고 가정한다면, 메뉴 버튼을 누름으로서 이벤트가 발생하게 되고, 조건식으로 dark-theme 가 적용되어 있는지 확인을 합니다. 만일 적용되어 있다면 클래스를 지워주고, 아니라면 추가하여 스위치 효과를 구현할 수 있습니다.
즉, dark-theme 가 적용되면, background-color 는 검정색, color 는 흰색으로 변경됩니다.
아래의 구현을 toggle을 사용 시 간단하게 변경해 줄 수 있습니다.
$menu.addEventListener('click', () => {
body.classList.toggle('dark-theme');
})
자동적으로 만약 dark-theme 가 있다면 테마를 지워주고, 없다면 추가해줍니다. 즉, 메서드 add(), remove()를 동시해 구현시켜줍니다.
2. localStorage
toggle을 사용하여, 테마를 변경해주는 것을 구현해봤습니다.
별 문제가 없어보이지만, 웹사이트를 다크모드로 감상하다가 새로고침을 누르게된다면 다크모드가 유지가 되지 않는다는 문제가 발생하게 됩니다.
즉 이벤트가 초기화가 되어 다시 다크모드 버튼을 클릭해주어야 할 것입니다.
사실 그냥 다크모드 다시 눌러주면 해결되는 일이라 큰 불편함은 없을 수 있으나, localStorage를 활용하면 이 역시 해결할 수 있습니다.
로컬 스토리지(localStorage) 는 html5에서 추가된 저장소로서, 간단하게 key, value를 저장할 수 있습니다. 로컬 스토러지는 웹페이지의 세션이 끝나더라도 데이터가 지워지지 않습니다. 이러한 저장 데이터는 동일한 컴퓨터에서 다른 브라우져나 다른 컴퓨터에서 같은 브라우저를 사용하는 경우에만 영속성을 유지할 수 있습니다. 로컬 스토리지는 window 객체 안에 들어있습니다. (window.localStorage)
// setItem()을 사용하여 아이템을 추가할 수 있습니다.
localStorage.setItem(key, value)
// 아이템을 읽기 위해 getItem()을 사용합니다.
localStorage.getItem(key)
// 아이템을 제거하기 위해 removeItem()을 사용합니다.
localStorage.removeItem(key)
// 데이터를 모두 지웁니다.
localStorage.clear()
// 저장된 데이터의 갯수를 알 수 있습니다.
localStorage.length
이제 localStorage가 어떤식으로 적용되는지 다크모드를 구현해보면서 살펴보겠습니다.
1. HTML
테마를 변경할 수 있는 버튼입니다. 두가지 해와 달 아이콘으로 화면에 표시되고, 평소 테마에는 해 모양의 아이콘은 나오지 않습니다.
<button type="button" class="theme-toggle-button">
<i class='bx bxs-moon theme-off'></i>
<i class="bx bxs-sun theme-on"></i>
</button>
2. CSS
위에서 살펴본 기본적인 dark-theme 적용값과, dark-theme 가 적용되었을 시 각각 해와 달 아이콘의 표현 유무를 클래스로 지정해두었습니다.
body{
background-color: #f3f3fe;;
color: #000;;
}
body.dark-theme{
background-color: #000; /* 검정색 */
color: #f3f3fe; /* 흰 계통 색*/
}
/* 아이콘에 부여한 클래스. 평소 display= none 을 유지함. */
.theme-on{
display: none;
}
.dark-theme .theme-off{
display: none;
}
/* 다크테마가 적용되었을 때 아이콘이 화면에 나타난다. */
.dark-theme .theme-on{
display: block;
}
3. Javascript
하나하나 각 단계별로 살펴보겠습니다.
1) 웹 세션에서 key값 'darkTheme' 존재하는지 확인하기.
// dark-theme 적용하기 (달 클릭시 해로 바뀌면서 전체 색상 리버스)
const $body = document.body;
const $themeToggleButton = document.querySelector('.theme-toggle-button');
const currentTheme = localStorage.getItem('darkTheme'); // 읽어오기
if(currentTheme){
$body.classList.add('dark-theme');
}
querySelector로 버튼을 불러 온 뒤, 웹페이지 실행 시 자동으로 웹 세션에 key 값인 'darkTheme'가 있는지 확인합니다.
순서가 먼저 확인부터 나와 햇갈릴 수 있지만, 뒤에서 setItem() 을 사용하여 ket, value를 저장해 줄 것입니다.
(먼저 확인하는 이유는 웹 페이지를 새로 로드하였을 때, key 값이 존재한다면 그대로 dark-theme 를 유지하기 위해서입니다.)
currentTheme 가 Ture 라면, 즉 key 값이 존재한다면, dark-theme 를 추가해줍니다.
2) 클릭 이벤트를 통해서 key 값의 세션 저장유무를 결정시켜주기
아이콘 버튼을 클릭함으로서 웹 사이트 내 dark-theme 클래스를 toggle 해줄 수 있습니다. 이제 일어날 수 있는 상황을 가정해보겠습니다.
처음에는 dark-theme 가 적용되어있지 않았다고 가정하겠습니다. 만약 버튼을 클릭하여 dark-theme 를 추가하였다면, 이를 확인하여 localStorage에 key값과 value 값을 추가해줍니다. 이 상태로 웹사이트를 종료하게 되면, key 값은 세션에 그대로 남아있게 되고, 다시 웹사이트 실행 시 앞서서 key 값을 확인할것이며 확인 후 dark-theme 를 add() 로 추가할 것입니다. 즉, 다크테마는 유지됩니다.
이제 적용되어 있는 dark-theme 를 버튼을 눌러 지우도록 하겠습니다. 조건문에 의해 dark-theme 가 지워지게 되면, removeItem() 을 통해 세션에 저장해두었던 key 값인 'darkTheme' 를 지워주게 됩니다. 이제 사이트를 다시 새로고침 하면, key 값이 존재하지 않기 때문에, add() 메서드를 적용시키지 않습니다. (조건문에서 currentTheme 가 거짓이기 때문). 따라서 여전히 화면은 dark-theme 가 적용되지 않습니다.
const changeTheme = () => {
$body.classList.toggle('dark-theme');
// 만일 클릭을 통해 dark-theme 클래스가 생성이 되었다면.
if($body.classList.contains('dark-theme')){
localStorage.setItem('darkTheme', 'active'); // 추가하기. key = darkTheme , value = active
}else{
localStorage.removeItem('darkTheme'); // 클릭을 통해 클래스가 사라졌다면, 사이트내 키값도 삭제한다.
}
}
$themeToggleButton.addEventListener('click', changeTheme);
'Programing > Javascript' 카테고리의 다른 글
[Deep Dive] 제어문 (0) | 2022.10.21 |
---|---|
[Deep Dive] 연산자 (0) | 2022.10.19 |
[Deep Dive] 데이터 타입 (2) | 2022.10.07 |
[Deep Dive] 표현식과 문 (0) | 2022.10.06 |
[Deep Dive] 변수 (0) | 2022.10.06 |