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%;
}