- 노마드코더의 하단 강의 수강완료 후 작성하는 게시글입니다.
바닐라 JS로 크롬 앱 만들기 – 노마드 코더 Nomad Coders
Javascript For Beginners
nomadcoders.co
- 소스코드 : https://github.com/cjy921004/mywebpage
GitHub - cjy921004/mywebpage
Contribute to cjy921004/mywebpage development by creating an account on GitHub.
github.com
<조건>
- 배경화면은 새로고침시마다 랜덤으로 바뀌도록 함
- 중앙에는 현재 날씨가 초 단위로 보여짐
- 오른쪽 상단에 현재위치와, 해당 위치의 날씨와 온도 표시
- 왼쪽 하단에는 명언과 작가가 표시되는데, 새로고침시마다 랜덤으로 보여짐
- 초기에 사용자의 이름 입력하도록 하고, 이름 입력 시 Hello, 이름이 보여짐
- todo 리스트 작성 칸에 목록을 작성하면 아래에 리스트로 각 항목이 추가됨
- 리스트에 x버튼 클릭 시 리스트 삭제됨
- localStorage에 사용자의 이름(name)과 todo리스트 항목들이 저장됨
- 새로고침하여도 이름과 todo리스트 항목들이 이전 상태 그대로 출력되어야 함
- 완성본 이미지
- 초기화면에서는 이름 입력 칸 나오고, 이름 입력 후에는 입력 칸 사라지고 해당 자리에 Hello,이름 출력


- To do list 작성 칸에 목록 작성 시 아래 리스트로 추가되며, 각 항목의 오른쪽 x 누르면 항목 사라짐


- 새로고침하면 배경이미지와 왼쪽 하단의 명언이 랜덤으로 바뀌며, 이름과 할일목록은 그대로 유지되어 있음

- 따로 DB를 이용하지 않고, 가장 기본인 Local Storage를 이용했으며, 저장된 내용

- index.html
<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">
<link rel="stylesheet" href="css/style.css">
<title>Vanilla</title>
</head>
<body>
<form id="login-form" class="hidden">
<input required maxlength=15 type="text" placeholder="What is your name?" />
<button class="hidden">LogIn</button>
</form>
<h2 id="clock">00:00:00</h2>
<h1 id="greeting" class="hidden"></h1>
<form id="todo-form">
<input id="todo-input" required placeholder="Write a To Do here!" cols="30" rows="3">
<button class="hidden">Add</button>
</form>
<ul id="todo-list"></ul>
<div id="quote">
<span class="quote"></span>
<span class="author"></span>
</div>
<div id="weather">
<span class="area"></span><br>
<span class="weather"></span>
</div>
<script src="js/greeting.js"></script>
<script src="js/clock.js"></script>
<script src="js/quotes.js"></script>
<script src="js/background.js"></script>
<script src="js/todo.js"></script>
<script src="js/weather.js"></script>
</body>
</html>
- style.css
<css />
body,html{
text-align: center;
height: 95%;
background-position: center;
background-repeat: no-repeat;
background-size: cover;
}
.hidden{
display: none;
}
#clock{
position: absolute;
left: 50%;
top:20%;
transform: translate(-50%,-50%);
color: whitesmoke;
text-shadow: 2px 7px 6px gray;
font-size: 100px;
font-family: 'Times New Roman', Times, serif;
}
#login-form{
position: absolute;
left: 50%;
top:20%;
transform: translate(-50%,-50%);
}
#greeting{
text-shadow: 2px 7px 6px gray;
position: absolute;
left: 50%;
top:20%;
transform: translate(-50%,-50%);
color: whitesmoke;
font-family: 'Times New Roman', Times, serif;
}
#todo-form{
color: whitesmoke;
position: absolute;
left: 50%;
top: 50%;
transform: translate(-50%,-50%);
font-family: 'Times New Roman', Times, serif;
}
#todo-list{
font-weight: bold;
font-size: 15px;
text-shadow: 4px 7px 20px black;
font-style: bold;
color: whitesmoke;
position: absolute;
left: 50%;
top: 50%;
transform: translate(-50%);
font-family:Arial, Helvetica, sans-serif;
}
#quote{
text-shadow: 2px 7px 6px gray;
color: whitesmoke;
font-size: 13px;
position: absolute;
left: 1%;
top:95%;
font-style: italic;
font-family: serif;
}
#weather{
float: right;
text-align: right;
text-shadow: 2px 7px 6px gray;
color: whitesmoke;
font-family: 'Times New Roman', Times, serif;
}
li button{
background-color: transparent;
border-color: transparent;
}
input{
font-size: 15px;
color: white;
background-color: transparent;
border-top: none;
border-left: none;
border-right: none;
border-bottom: 1.5px solid black;
text-shadow: 2px 7px 6px white;
width: 100%;
}
input::placeholder{
color:whitesmoke;
text-shadow: 2px 7px 6px gray;
text-align: center;
}
- background.js : img 폴더에 저장된 사진들을 랜덤으로 배경화면으로 설정
<javascript />
const imges =["1.jpg","2.jpg","3.jpg","4.jpg","5.jpg"];
const chosenImage = imges[Math.floor(Math.random()*imges.length)];
document.body.style.backgroundColor = "white";
const url = "img/"+chosenImage;
document.body.style.backgroundImage = "url('" + url + "')";
- clock.js : 현재 시간을 화면 중앙에 출력
<javascript />
const clock = document.querySelector("h2#clock");
function getClock() {
const date = new Date();
const hours = date.getHours().toString().padStart(2, "0")
const minutes = date.getMinutes().toString().padStart(2, "0")
const seconds = date.getSeconds().toString().padStart(2, "0")
clock.innerText = `${hours}:${minutes}:${seconds}`;
}
getClock();
setInterval(getClock, 1000);
- padStart : 문자열을 원하는 길이로 고정하고, 만약 그 길이보다 짧으면 앞에 "0"을 추가하도록 해주는 함수
-greeting.js : 사용자가 이름을 입력하면, Hello,이름이 출력됨
<javascript />
const loginForm = document.querySelector("#login-form");
const loginInput = document.querySelector("#login-form input");
const loginBtn = document.querySelector("#login-form button");
const greeting = document.querySelector("#greeting");
const HIDDEN_CLASSNAME = "hidden";
const USERNAME_KEY = "username";
function onLoginSubmit(event) {
event.preventDefault(); // 기본행동발생막기 새로고침x
const username = loginInput.value;
loginForm.classList.add(HIDDEN_CLASSNAME);
localStorage.setItem("username", username);
paintGreeting(username);
}
function paintGreeting(username){
greeting.innerText = `Hello, ${username}`;
greeting.classList.remove(HIDDEN_CLASSNAME);
}
const savedUsername = localStorage.getItem(USERNAME_KEY);
if (savedUsername === null) {
loginForm.addEventListener("submit", onLoginSubmit);
loginForm.classList.remove(HIDDEN_CLASSNAME);
} else {
paintGreeting(savedUsername);
}
- quotes.js : 배열에 명언들을 저장해놓고, 해당 명언들을 랜덤으로 출력
<javascript />
const quotes = [
{
quote: "They must often change who would be constant in happiness or wisdom.",
author: "Confucius"
},
{
quote: "Age is no guarantee of maturity.",
author: "Lawana Blackwell"
},
{
quote: "Youth isn’t always all it’s touted to be.",
author: "Lawana Blackwell"
},
{
quote: "You will face many defeats in life, but never let yourself be defeated.",
author: "Maya Angelou"
},
{
quote: "The greatest glory in living lies not in never falling, but in rising every time we fall.",
author: "Nelson Mandela"
},
{
quote: "Life is either a daring adventure or nothing at all.",
author: "Helen Keller"
}];
const quote = document.querySelector("#quote .quote");
const author = document.querySelector("#quote .author");
const todayQuote = quotes[Math.floor(Math.random()*quotes.length)];
quote.innerText = todayQuote.quote;
author.innerText = '-'+todayQuote.author;
- todo.js : todo리스트 출력
<javascript />
const toDoForm = document.querySelector("#todo-form");
const toDoList = document.querySelector("#todo-list");
const toDoInput = document.querySelector("#todo-input");
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((item)=> (item.id).toString()!==li.id);
saveToDos();
}
function paintToDo(newToDoObj) {
const list = document.createElement("li");
list.id= newToDoObj.id;
const span = document.createElement("span");
const delteBtn = document.createElement("button");
delteBtn.innerText = "❌";
delteBtn.addEventListener("click", deleteToDo);
list.appendChild(span);
list.appendChild(delteBtn);
span.innerText = newToDoObj.text;
toDoList.appendChild(list);
}
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) {
const parsedToDos = JSON.parse(savedToDos);
toDos= parsedToDos;
parsedToDos.forEach(toDo => {
paintToDo(toDo);
});
}
- weather.js : 오른쪽 상단에 현재 위치와, 날씨, 온도를 출력
<javascript />
const API_KEY = "9dc27644395e1b8631cb949f7da6ceaf";
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 => {
const weather = document.querySelector("#weather .weather");
const area = document.querySelector("#weather .area");
area.innerText = data.name;
weather.innerText = `${data.weather[0].main} /${data.main.temp}℃`;
}));
}
function onGeoError(){
console.log("Can't find");
}
navigator.geolocation.getCurrentPosition(onGeoOk,onGeoError);
'FRONTEND > JavaScript' 카테고리의 다른 글
[JavaScript] setTimeout 함수로 디바운싱 / 쓰로틀링 구현하기 (0) | 2023.08.28 |
---|---|
[ JavaScript ] 비동기 통신 - Promise, async, await (0) | 2023.01.23 |
[ 생활코딩 - WEB2 JavaScript ] 강의 내용 정리 (0) | 2022.12.08 |
[코드잇 - 자바스크립트 객체 지향 기본기] 2. 객체지향 프로그래밍의 4개의 기둥 : 추상화, 캡슐화, 상속, 다형성 (0) | 2022.11.22 |
[코드잇 - 자바스크립트 객체 지향 기본기] 1. 객체와 클래스 (0) | 2022.11.22 |