2023. 8. 8. 23:08ㆍ공부 중/Node.js
1. 쿠키를 활용해서 다크모드 구현하기
기존 페이지는 리로딩할 때마다 다크모드가 꺼지는 문제가 있었다.
그래서 다른 페이지로 이동하거나 리로딩해도 다크모드가 그대로 유지되도록 해보자.
가. 쿠키 생성
다크모드에 관한 정보를 저장하는 쿠키를 만든다.
1) cookie-parser 설치
npm install cookie-parser
2) 미들웨어 추가
// app.js
const cookieParser = require('cookie-parser');
const checkCookie = require('./lib/checkCookie.js');
...
app.use(cookieParser());
app.use(checkCookie.checkDarkMode);
...
// ./lib/checkCookie.js
const express = require('express');
module.exports.checkDarkMode = (req, res, next)=>{
res.cookie('dark-mode', true);
next();
}
cookieParser
와 새로 만든 checkCookie.checkDarkMode
미들웨어를 추가한다.
app.use(checkCookie.checkDarkMode);
: 모든 요청에 대하여checkCookie.checkDarkMode
를 실행한다.
사실 모든 요청마다 checkCookie.checkDarkMode
가 필요한 것은 아니라서 http get method에만 동작하도록 수정한다.
app.get('*', checkCookie.checkDarkMode);
dark-mode
쿠키가 생성된 것을 알 수 있다.
나. 쿠키 읽기
지금까지는 매번 dark-mode
쿠키의 값이 true
로 초기화된다.
쿠키가 없으면 생성해야 하지만 기존에 쿠키가 존재한다면 다시 생성하지 않도록 수정한다.
+ 쿠키의 이름을 darkMode
로, default 값을 false
로 수정한다.
module.exports.checkDarkMode = (req, res, next)=>{
if(req.cookies.darkMode === undefined)
res.cookie('darkMode', false);
next();
}
다. 페이지 로딩 때 모드 반영하기
1) 클라이언트에서 원하는 쿠키값을 읽는 방법
// 주어진 이름의 쿠키를 반환하는데,
// 조건에 맞는 쿠키가 없다면 undefined를 반환합니다.
function getCookie(name) {
let matches = document.cookie.match(new RegExp(
"(?:^|; )" + name.replace(/([\.$?*|{}\(\)\[\]\\\/\+^])/g, '\\$1') + "=([^;]*)"
));
return matches ? decodeURIComponent(matches[1]) : undefined;
}
위에 코드를 응용해서 다음 코드를 추가한다.
...
function getCookie(name) {
let matches = document.cookie.match(new RegExp(
"(?:^|; )" + name.replace(/([\.$?*|{}\(\)\[\]\\\/\+^])/g, '\\$1') + "=([^;]*)"
));
return matches ? decodeURIComponent(matches[1]) : undefined;
}
console.log(getCookie('darkMode'));
2) 페이지 로딩 때 쿠키값을 읽어서 모드 적용하기
// darkMode.js <- color.js에서 개명함.
...
function nightDayHandler() {
if(getCookie('darkMode') === 'true'){
Body.setBackgroundColor("black");
Body.setColor("white");
Links.setColor("white");
Lists.setColor("black");
} else {
Body.setBackgroundColor("white");
Body.setColor("black");
Links.setColor("black");
Lists.setColor("white");
}
}
nightDayHandler()
가 호출되면 쿠키값에 맞춰 밝기를 조절한다.
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<meta http-equiv="X-UA-Compatible" content="IE=edge" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>WEB - ${req.title}</title>
<link rel="stylesheet" href="/static/css/style.css">
<script src="/static/js/crudBtn.js"></script>
<script src="/static/js/darkMode.js"></script>
<script>nightDayHandler()</script>
</head>
<script>nightDayHandler()</script>
을 추가해서 페이지가 로딩될 때 쿠키값대로 다크모드를 적용하려고 했다.
3) Uncaught TypeError: Cannot read properties of null (reading 'style')
darkMode.js:3 Uncaught TypeError: Cannot read properties of null (reading 'style')
at Object.setBackgroundColor (darkMode.js:3:35)
at nightDayHandler (darkMode.js:38:10)
at (index):12:17
아직 DOM에 완전히 자리 잡기 전에 스크립트가 동작해서 Cannot read properties of null
error를 발생했다.
문제를 해결하기 위해서는 DOM에 콘텐츠가 완전히 로딩되었는지 기다리는 리스너를 추가한다.
<script>
document.addEventListener("DOMContentLoaded", ()=>{
nightDayHandler();
});
</script>
이제 처음에 페이지를 로딩할 때 쿠키값대로 화면밝기가 조절된다.
출처 : https://isotropic.co/how-to-fix-cannot-read-property-style-of-null-in-javascript/
라. 버튼을 눌러서 모드 변경하기
1) 클라이언트에서 쿠키값을 변경하는 법
document.cookie = "user=John"; // 이름이 'user'인 쿠키의 값만 갱신함
버튼을 누르면 쿠키를 값을 바꾸고 쿠키값에 따라서 화면밝기를 바꾸도록 만든다.
function changeDarkMode(self) {
if (self.value === "night") {
document.cookie = "darkMode=false";
self.value = "day";
} else {
document.cookie = "darkMode=true";
self.value = "night";
}
nightDayHandler();
}
//html
<input type="button" value="night" onclick="changeDarkMode(this)"/> </div>
2) 버그 : /topic
에서 버튼을 누르면 쿠키가 중복 생성됨
/
에서는 문제없이 잘 돌아간다.
하지만 /
가 아닌 /topic
에서 버튼을 누르면 쿠키가 중복해서 생성되는 문제가 발생한다.
버튼을 눌렀을 경우에만 버그가 발생하기 때문에 아래 코드의 문제일 가능성이 크다.
function changeDarkMode(self) {
if (self.value === "night") {
document.cookie = "darkMode=true";
self.value = "day";
} else {
document.cookie = "darkMode=false";
self.value = "night";
}
nightDayHandler();
}
/
가 아닌 /topic
에서 쿠키의 값을 수정하면 쿠키의 path
가 /topic
으로 설정되어 나타나는 문제다.
function changeDarkMode(self) {
if (self.value === "night") {
document.cookie = "darkMode=true; Path=/";
self.value = "day";
} else {
document.cookie = "darkMode=false; Path=/";
self.value = "night";
}
nightDayHandler();
}
path
옵션을 추가해서 해결한다.
3) 버그 : 버튼의 value 오류
버튼이 쿠키에 값을 받아와서 value를 선택하도록 수정한다.
지금은 쿠키의 값과는 상관없이 무조건 처음에는 night로 고정되어 있다.
쿠키값에 맞는 버튼의 value를 설정하도록 변경한다.
const NightDayBtn = { // 추가!
getValue: ()=>{
let btn = document.getElementById("nightDayBtn");
return btn.value;
},
setValue: ()=>{
let btn = document.getElementById("nightDayBtn");
if(getCookie('darkMode') === 'true'){
btn.value = "day";
}else{
btn.value = "night";
}
console.log(btn.value);
}
}
function nightDayHandler() {
if(getCookie('darkMode') === 'true'){
Body.setBackgroundColor("black");
Body.setColor("white");
Links.setColor("white");
Lists.setColor("black");
NightDayBtn.setValue(); // 추가!
} else {
Body.setBackgroundColor("white");
Body.setColor("black");
Links.setColor("black");
Lists.setColor("white");
NightDayBtn.setValue(); // 추가!
}
}
function changeDarkMode() {
if (NightDayBtn.getValue() === "night") { // 변경!
document.cookie = "darkMode=true; Path=/";
} else {
document.cookie = "darkMode=false; Path=/";
}
nightDayHandler();
}
<input id="nightDayBtn" type="button" value="night" onclick="changeDarkMode()"/> </div>
이제 nightDayHandler()
만 실행하면 알맞은 버튼의 value가 설정된다.
'공부 중 > Node.js' 카테고리의 다른 글
[Express] Session이란? (0) | 2023.08.19 |
---|---|
[Node.js] 쿠키의 한계 (0) | 2023.08.10 |
[Node.js] 쿠키 옵션 (0) | 2023.07.07 |
[Node.js] 세션 쿠키, 영구 쿠키 (0) | 2023.07.06 |
[Node.js] 쿠키 생성, 읽기 (0) | 2023.07.06 |