WEB/JavaScript
[크롬 앱 만들기] code 완성본
Harimad
2022. 1. 19. 16:47

내 깃 저장소: https://github.com/Harimad/portfolio_todo
https://harimad.github.io/portfolio_todo/ <- 최종 사이트
아래는 nomadcoder git 파일 최종본
index.html
<!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>MoMentum App from Tim Lee</title>
<link rel="stylesheet" href="css/style.css">
</head>
<body>
<!-- greeting -->
<form class="hidden" id="login-form">
<input type="text" required maxlength="15" placeholder="What's your name?">
<!-- <input class="button" type="submit" value="Log in"> -->
</form>
<h1 class="hidden" id="greeting"></h1>
<!-- clock -->
<h2 id="clock">00:00:00</h2>
<!-- todo -->
<form id="todo-form">
<input type="text" placeholder="Write a Todo here">
</form>
<ul id="todo-list"></ul>
<!-- quotes -->
<div id="quote">
<span></span>
<span></span>
</div>
<!-- weather -->
<div id="weather">
<span></span>
<span></span>
</div>
<!-- bacground -->
<div class="background-cover"></div>
<script src="js/greeting.js"></script>
<script src="js/clock.js"></script>
<script src="js/background.js"></script>
<script src="js/quotes.js"></script>
<script src="js/todo.js"></script>
<script src="js/weather.js"></script>
</body>
</html>
greeting.js
const $loginForm = document.querySelector('#login-form');
const $loginInput = document.querySelector('#login-form input:first-child');
const $greeting = document.querySelector('#greeting');
const HIDDEN_CLASSNAME = 'hidden';
const USERNAME_KEY = 'username';
const savedUsername = localStorage.getItem(USERNAME_KEY);
if (savedUsername === null) {
$loginForm.classList.remove(HIDDEN_CLASSNAME);
$loginForm.addEventListener('submit', onLoginSubmit);
} else {
paintGreetings(savedUsername);
}
function onLoginSubmit(event) {
event.preventDefault();
$loginForm.classList.add(HIDDEN_CLASSNAME);
const username = $loginInput.value;
localStorage.setItem(USERNAME_KEY, username);
paintGreetings(username);
}
function paintGreetings(username) {
$greeting.innerText = `Hello ${username}`;
$greeting.classList.remove(HIDDEN_CLASSNAME);
}
clock.js
const $clock = document.querySelector('#clock');
function getClock() {
const date = new Date();
const hours = String(date.getHours()).padStart(2, '0');
const minutes = String(date.getMinutes()).padStart(2, '0');
const seconds = String(date.getSeconds()).padStart(2, '0');
$clock.innerText = `${hours}:${minutes}:${seconds}`;
}
getClock();
setInterval(getClock, 1000);
background.js
const imgUrl = ['img/a.jpg', 'img/b.jpg', 'img/c.jpg', 'img/d.jpg', 'img/e.jpg', 'img/f.jpg', 'img/g.jpg', 'img/h.jpg', 'img/i.jpg', 'img/j.jpg', 'img/k.jpg', 'img/l.jpg'];
function changeImg() {
const $body = document.querySelector('body');
const randomNum = Math.floor(Math.random() * imgUrl.length);
const $bgImg = document.createElement('img');
$bgImg.classList.add('background');
$bgImg.src = imgUrl[randomNum];
$body.appendChild($bgImg);
}
changeImg();
quotes.js
const quotes = [
{
quote: "The way to get started is to quit talking and begin doing.",
author: "Walt Disney",
},
{
quote: "Life is what happens when you're busy making other plans.",
author: "John Lennon",
},
{
quote:
"The world is a book and those who do not travel read only one page.",
author: "Saint Augustine",
},
{
quote: "Life is either a daring adventure or nothing at all.",
author: "Helen Keller",
},
{
quote: "To Travel is to Live",
author: "Hans Christian Andersen",
},
{
quote: "Only a life lived for others is a life worthwhile.",
author: "Albert Einstein",
},
{
quote: "You only live once, but if you do it right, once is enough.",
author: "Mae West",
},
{
quote: "Never go on trips with anyone you do not love.",
author: "Hemmingway",
},
{
quote: "We wander for distraction, but we travel for fulfilment.",
author: "Hilaire Belloc",
},
{
quote: "Travel expands the mind and fills the gap.",
author: "Sheda Savage",
},
];
function quoteGenerator() {
const $quote = document.querySelector('#quote span:first-child');
const $author = document.querySelector('#quote span:last-child');
const todayQuoteObj = quotes[Math.floor(Math.random() * quotes.length)];
$quote.innerText = todayQuoteObj.quote;
$author.innerText = todayQuoteObj.author;
}
quoteGenerator();
setInterval(quoteGenerator, 10000);
todo.js
const toDoForm = document.getElementById("todo-form");
const toDoInput = document.querySelector("#todo-form input");
const toDoList = document.getElementById("todo-list");
const TODOS_KEY = "todos";
let toDos = [];
function saveToDos() {
localStorage.setItem(TODOS_KEY, JSON.stringify(toDos));
}
function deleteToDo(event) {
const li = event.target.parentElement;
li.remove();
toDos = toDos.filter((toDo) => toDo.id !== parseInt(li.id));
saveToDos();
}
function paintToDo(newTodo) {
const li = document.createElement("li");
li.id = newTodo.id;
const span = document.createElement("span");
span.innerText = newTodo.text;
const button = document.createElement("button");
button.innerText = "❌";
button.addEventListener("click", deleteToDo);
li.appendChild(span);
li.appendChild(button);
toDoList.appendChild(li);
}
function handleToDoSubmit(event) {
event.preventDefault();
const newTodo = toDoInput.value;
toDoInput.value = "";
const newTodoObj = {
text: newTodo,
id: Date.now(),
};
toDos.push(newTodoObj);
paintToDo(newTodoObj);
saveToDos();
}
toDoForm.addEventListener("submit", handleToDoSubmit);
const savedToDos = localStorage.getItem(TODOS_KEY);
if (savedToDos !== null) {
const parsedToDos = JSON.parse(savedToDos);
toDos = parsedToDos;
parsedToDos.forEach(paintToDo);
}
weather.js
const $weather = document.querySelector('#weather span:first-child');
const $city = document.querySelector('#weather span:last-child');
const API_KEY = "2987c8637eaa35497d222f12170acb5d";
function onGeoOk(position) {
const lat = position.coords.latitude;
const lon = position.coords.longitude;
const url = `https://api.openweathermap.org/data/2.5/weather?lat=${lat}&lon=${lon}&appid=${API_KEY}&units=metric`;
fetch(url)
.then((response) => response.json())
.then((data) => {
$city.innerText = data.name;
$weather.innerText = `${data.weather[0].main} | ${data.main.temp}`
})
}
function onGeoError(err) {
console.warn(`ERROR(${err.code}): ${err.message}`);
}
navigator.geolocation.getCurrentPosition(onGeoOk, onGeoError);
style.css
.hidden {
display: none;
}
.background {
margin: 0 auto;
position: absolute;
width: 100%;
height: 100%;
background-repeat: no-repeat;
background-size: cover;
}
.background-cover {
margin: 0 auto;
position: absolute;
width: 100%;
height: 100%;
background-color: rgba(0, 0, 0, 0.4);
z-index: 1;
}
body {
margin: 0 auto;
font-family: "Courier New", Courier, monospace;
}
ul {
list-style: none;
}
button {
background-color: transparent;
background-repeat: no-repeat;
border: none;
cursor: pointer;
overflow: hidden;
outline: none;
}
input[type="text"] {
width: 200px;
height: 25px;
color: white;
background: transparent;
border: none;
border-bottom: 1px solid white;
outline: none;
}
input[type="text"]:focus {
border-bottom: 1px solid palegreen;
}
input::placeholder {
color: whitesmoke;
}
#login-form {
position: absolute;
top: 40%;
left: 50%;
transform: translate(-50%, -50%);
z-index: 2;
text-align: center;
font-size: 15px;
color: whitesmoke;
opacity: 70%;
}
#greeting {
position: absolute;
top: 40%;
left: 50%;
transform: translate(-50%, -50%);
z-index: 2;
text-align: center;
font-size: 30px;
color: whitesmoke;
opacity: 80%;
}
#clock {
position: absolute;
top: 20%;
left: 50%;
transform: translate(-50%, -50%);
z-index: 2;
text-align: center;
font-size: 90px;
color: whitesmoke;
opacity: 60%;
}
#todo-form {
position: absolute;
top: 50%;
left: 50%;
transform: translate(-50%, -50%);
z-index: 2;
text-align: center;
font-size: 15px;
color: whitesmoke;
opacity: 90%;
}
#todo-list {
position: absolute;
top: 60%;
left: 45%;
transform: translate(-50%, -50%);
z-index: 2;
text-align: center;
width: 150px;
font-size: 20px;
color: white;
opacity: 90%;
}
#todo-list li {
display: flex;
justify-content: space-around;
}
.todo-element,
.todo-button {
display: inline-block;
}
#quote {
position: absolute;
top: 90%;
left: 50%;
transform: translate(-50%, -50%);
z-index: 2;
text-align: center;
font-size: 14px;
color: whitesmoke;
opacity: 70%;
}
#weather {
position: absolute;
top: 10%;
left: 90%;
transform: translate(-50%, -50%);
z-index: 2;
text-align: center;
font-size: 15px;
color: whitesmoke;
opacity: 80%;
}