예전에 한 번 만들어 봤었던 노마드코더의 To-do-list를 복습 겸 다시 만들어봤다.
HTML의 기본적인 구성은 아래와 같다.
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<meta property="og:type" content="website">
<meta property="og:title" content="To-do-list">
<meta property="og:description" content="To-do-list page">
<meta property="og:image" content="./ogp.jpg">
<meta property="og:url" content="https://moon-sangho.github.io/To-do-list/">
<link rel="stylesheet" href="style.css">
<title>To-do-list</title>
</head>
<body>
<div class="js-clock">
<h1>00:00</h1>
</div>
<form class="js-form form">
<input type="text" placeholder="What is your name?">
</form>
<h4 class="js-greetings greetings"></h4>
<form class="js-toDoForm">
<input type="text" placeholder="Write a to do">
</form>
<ul class="js-toDoList">
</ul>
<div class="js-weather"></div>
<script src="clock.js"></script>
<script src="greeting.js"></script>
<script src="todo.js"></script>
<script src="bg.js"></script>
<script src="weather.js"></script>
</body>
</html>
const clockContainer = document.querySelector(".js-clock");
const clockTitle = clockContainer.querySelector("h1");
function getTime() {
const date = new Date();
const minutes = date.getMinutes();
const hours = date.getHours();
const seconds = date.getSeconds();
clockTitle.innerText = `${hours < 10 ? `0${hours}` : hours}:${minutes < 10 ? `0${minutes}` : minutes}:${seconds < 10 ? `0${seconds}` : seconds}`;
}
function init() {
getTime();
setInterval(getTime, 1000);
}
init();
현재 시간을 얻기 위해 함수 getTime( )을 만든다.
상수 date에 현재 날짜와 시간 등을 저장한다. 아래는 console창 실행 결과이다.
시간, 분, 초를 각각 저장하고 HTML의 h1에 삽입되도록 설정한다.
${hours < 10 ? `0${hours}` : hours}
는 삼항연산자 형태이다.
hours가 미만이면 0${hours} 의 형태로 출력하고 그렇지 않으면 hours로 출력하라는 의미이다.
예를 들어, 9:10:32 에서 9 앞에 0을 붙여 미관상 더 좋게 보이도록 하기 위함이다.
init 함수에 getTime(), setinterval(getTime,1000)을 넣어 현재 시간이 1초마다 갱신되도록 한다.
const form = document.querySelector(".js-form");
const input = form.querySelector("input");
const greeting = document.querySelector(".js-greetings");
const USER_LS = "currentUser";
const SHOWING_CN = "showing";
// localStorage에 사용자 이름 저장
function saveName(text) {
localStorage.setItem(USER_LS, text);
}
// 사용자 이름 입력 후 enter 시 localStorage에 저장
function handleSubmit(event) {
event.preventDefault();
const currentValue = input.value;
paintGreeting(currentValue);
saveName(currentValue);
}
// 사용자 이름 묻기
function askForName() {
form.classList.add(SHOWING_CN);
form.addEventListener("submit", handleSubmit);
}
// 인사말 출력 설정
function paintGreeting(text) {
form.classList.remove(SHOWING_CN);
greeting.classList.add(SHOWING_CN);
greeting.innerText = `Hello ${text}`
}
// localStorage 이름 저장 여부에 따라 사용자 이름 묻기 or 인사말 출력
function loadName() {
const currentUser = localStorage.getItem(USER_LS);
if (currentUser === null) {
askForName();
} else {
paintGreeting(currentUser);
}
}
function init() {
loadName();
}
init();
loadName( ) 함수를 만들어 localStorage 이름 저장 여부에 따라 사용자 이름을 묻거나
인사말이 출력되도록 설정한다.
사용자 이름이 저장되어있지 않다면 askForName( )함수를 실행하고,
그렇지 않다면 인사말과 함께 사용자의 이름을 출력하는 함수인
paintGreeting(currentUser)를 실행시킨다.
const toDoForm = document.querySelector(".js-toDoForm");
const toDoInput = toDoForm.querySelector("input");
const toDoList = document.querySelector(".js-toDoList");
const TODOS_LS = 'toDos';
let toDos = [];
// to do list 삭제 기능 설정
function deleteTodo(event) {
const btn = event.target;
const li = btn.parentNode;
toDoList.removeChild(li);
const cleanToDos = toDos.filter(function(toDo) {
return toDo.id !== parseInt(li.id);
});
toDos = cleanToDos;
saveToDos();
}
// localStorage 저장 함수 생성
function saveToDos() {
localStorage.setItem(TODOS_LS, JSON.stringify(toDos));
}
// to do list 화면 출력 설정, localStorage 데이터 저장 형식 설정
function paintToDo(text) {
const li = document.createElement("li");
const delBtn = document.createElement("button");
delBtn.innerText = "❌";
delBtn.addEventListener("click", deleteTodo);
const span = document.createElement("span");
const newId = toDos.length + 1;
span.innerText = text;
li.appendChild(delBtn);
li.appendChild(span);
li.id = newId;
toDoList.appendChild(li);
const toDoObj = {
text: text,
id: newId
};
toDos.push(toDoObj);
saveToDos();
}
// to do list 출력
function handleSubmit(event) {
event.preventDefault();
const currentValue = toDoInput.value;
paintToDo(currentValue);
toDoInput.value = "";
}
// localStorage에 저장된 to do list 불러오기
function loadToDos() {
const loadedToDos = localStorage.getItem(TODOS_LS);
if (loadedToDos !== null) {
const parsedToDos = JSON.parse(loadedToDos);
parsedToDos.forEach(function(toDo) {
paintToDo(toDo.text);
});
}
}
function init() {
loadToDos();
toDoForm.addEventListener("submit", handleSubmit);
}
init()
화면에 출력되는 to-do-list를 localStorage에 저장되도록 하여 페이지 새로고침 시에도
정보가 남아있도록 했다.
여기서 짚고 넘어갈만한 부분은 JSON.parse와 JSON.stringify이며, 자세한 내용은
여기에서 볼 수 있다.
const body = document.querySelector("body");
const IMG_NUMBER = 5;
function paintImage(imgNumber) {
const image = new Image();
image.src = `img/${imgNumber + 1}.jpg`
image.classList.add('bgImage');
body.appendChild(image);
}
function genRandom() {
const number = Math.floor(Math.random() * IMG_NUMBER);
return number;
}
function init() {
const randomNumber = genRandom();
paintImage(randomNumber);
}
init();
Math.random( ) 메서드를 사용하여 새로고침을 할 때마다 5개의 배경화면 중 하나가
랜덤으로 적용되도록 설정했다.
const weather = document.querySelector(".js-weather");
const API_KEY = "5d6ffc4b865e4c543adc8cc997f1aebe"
const COORDS = "coords";
// 날씨 정보 받아오기
function getWeather(lat, lng) {
fetch(`https://api.openweathermap.org/data/2.5/weather?lat=${lat}&lon=${lng}&appid=${API_KEY}&units=metric`)
.then(function(response) {
return response.json();
})
.then(function(json) {
const temperature = json.main.temp;
const place = json.name;
weather.innerText = `${temperature}˚C @ ${place}`;
});
}
// localStorage에 위치 정보 저장
function saveCoords(coordsObj) {
localStorage.setItem(COORDS, JSON.stringify(coordsObj));
}
// 위치 정보 획득 시 localStorage에 저장 형태 설정
function handleGeoSuccess(position) {
const latitude = position.coords.latitude;
const longitude = position.coords.longitude;
const coordsObj = {
latitude, // 객체의 key와 이름을 같게 저장
longitude
};
saveCoords(coordsObj);
getWeather(latitude, longitude);
}
// 위치 정보 표시 에러
function handleGeoError() {
alert("Cant access geo location");
}
// 위치 정보 묻기
function askForCoords() {
navigator.geolocation.getCurrentPosition(handleGeoSuccess, handleGeoError);
}
// 위치 정보 저장 여부에 따라 위치 정보 요청 or 위치 정보 표시, 날씨 출력
function loadCoords() {
const loadedCoords = localStorage.getItem(COORDS);
if (loadedCoords === null) {
askForCoords();
} else {
const parsedCoords = JSON.parse(loadedCoords);
getWeather(parsedCoords.latitude, parsedCoords.longitude);
}
}
function init() {
loadCoords();
}
init();
위치 정보를 localStorage에 저장 후 fetch를 이용하여 날씨 API를 받아온 뒤 화면에 출력되도록 설정했다.
fetch 부분은 좀 더 공부해봐야 될 것 같다.
Ref.