Momentum
2022. 4. 25. 18:09ㆍStudy/JavaScript
바닐라 JS로 브라우저 크롬의 확장 프로그램인 Momentum을 구현하는 프로젝트
https://aluvy.github.io/www/momentum/
local storage를 활용한 로그인, to do list 구현과
Math.random()을 활용한 랜덤 background 및 명언 출력
setInterval을 활용한 시계, openweathermap 을 활용한 날씨 API 등
index.html
헤더에 아이콘 사용을 위해서 폰트어썸 코드를 입력했다.
<!DOCTYPE html>
<html lang="ko">
<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</title>
<script src="https://kit.fontawesome.com/cdd59ed73b.js" crossorigin="anonymous"></script>
<link rel="stylesheet" href="./css/style.css">
</head>
<body>
<div class="wrap">
<h1 class="hidden">Momentum</h1>
<article class="container">
<div class="clock">00:00:00</div>
<div class="greeting_wrap">
<form class="form-wrap hidden">
<input type="text" placeholder="What is your name?" required maxlength="15">
<button type="submit"><i class="fa-solid fa-unlock-keyhole"></i></button>
</form>
<h1 class="greeting hidden"></h1>
</div>
<div class="todo_wrap">
<form class="todo-form">
<input type="text" placeholder="Write a To Do and Press Enter" required>
</form>
<ul class="todo-list"></ul>
</div>
</article>
<div class="quote">
<span></span>
<span></span>
</div>
<div class="weather">
<i class="fa-solid"></i>
<span></span>
<span></span>
<p></p>
</div>
</div>
<script src="./js/greeting.js"></script>
<script src="./js/clocks.js"></script>
<script src="./js/quote.js"></script>
<script src="./js/background.js"></script>
<script src="./js/todo.js"></script>
<script src="./js/weather.js"></script>
</body>
</html>
js/greeting.js
로그인 전을 위한 .form-wrap 영역과
로그인 후를 위한 .greeting 영역으로 분리되어 있다.
username은 local storage에 저장되어, 페이지 새로고침 시에도 로그인 정보가 유지된다.
const formWrap = document.querySelector(".form-wrap");
const formWrapInput = formWrap.querySelector("input");
const formWrapButton = formWrap.querySelector("button");
const greeting = document.querySelector(".greeting");
const USERNAME = localStorage.getItem("username");
if(USERNAME == null){ // username이 비어있으면
formWrap.classList.remove("hidden");
formWrap.addEventListener("submit", HandlerFormSubmit);
formWrapInput.value = "";
} else { // username이 있으면
PrintGreeting(USERNAME);
}
function HandlerFormSubmit(event){
event.preventDefault();
const username = formWrapInput.value;
localStorage.setItem("username", username);
formWrap.classList.add("hidden");
PrintGreeting(username);
}
function PrintGreeting(username){
greeting.classList.remove("hidden");
greeting.innerHTML = `Hello <i class="fa-solid fa-face-smile"></i> ${username}!`;
}
js/clock.js
setInterval을 활용하여, 1초 단위로 흘러가는 디지털 시계를 구현했다.
padStart() 함수를 이용해 시계 숫자의 자리수를 맞춰줬다.
padStart()를 사용하기 위해 시,분,초를 문자처리 해줬다. String()
const clock = document.querySelector(".clock");
function setClock(){
const date = new Date();
const Hours = String(date.getHours()).padStart(2, "0");
const Menutes = String(date.getMinutes()).padStart(2, "0");
const seconds = String(date.getSeconds()).padStart(2, "0");
clock.innerHTML=`${Hours}:${Menutes}:${seconds}`;
}
setClock();
setInterval(setClock, 1000);
js/quotes.js
Math.Floor()와 Math.random(), array.length를 이용해 원하는 범위 내의 랜덤 숫자를 얻고, 이를 활용해 랜덤으로 글귀를 노출한다.
const quotes = [
{
quote: 'I never dreamed about success, I worked for it',
author: 'Estee Lauder'
},
{
quote: 'Do not try to be original, just try to be good.',
author: 'Paul Rand'
},
{
quote: 'Do not be afraid to give up the good to go for the great',
author: 'John D. Rockefeller'
},
{
quote: 'If you cannot fly then run. If you cannot run, then walk. And if you cannot walk, then crawl, but whatever you do, you have to keep moving forward.',
author: 'Martin Luther King Jr.'
},
{
quote: 'Our greatest weakness lies in giving up. The most certain way to succeed is always to try just one more time.',
author: 'Thomas Edison'
},
{
quote: 'The fastest way to change yourself is to hang out with people who are already the way you want to be',
author: 'REid Hoffman'
},
{
quote: 'Money is like gasoline during a road trip. You do not want to run out of gas on your trip, but you are not doing a tour of gas stations',
author: 'Tim O Reilly'
},
{
quote: 'Some people dream of success, while other people get up every morning and make it happen',
author: 'Wayne Huizenga'
},
{
quote: 'The only thing worse than starting something and falling.. is not starting something',
author: 'SEth Godin'
},
{
quote: 'If you really want to do something, you will find a way. If you do not, you will find an excuse.',
author: 'Jim Rohn'
},
];
const quote = document.querySelector('.quote span:first-child');
const author = document.querySelector('.quote span:last-child');
const quoteSelect = quotes[Math.floor(Math.random() * quotes.length)];
quote.innerHTML = quoteSelect.quote;
author.innerHTML = quoteSelect.author;
js/background.js
랜덤으로 배경화면 주소를 얻어온다.
const BackgroundImages = [
"0.jpg",
"1.jpg",
"2.jpg",
"3.jpg",
"4.jpg",
"5.jpg",
"6.jpg",
"7.jpg"
];
const wrap = document.querySelector(".wrap");
const SelectImage = BackgroundImages[Math.floor(Math.random()*BackgroundImages.length)];
wrap.style.backgroundImage = `url(./img/${SelectImage})`;
js/todo.js
local storage와 배열을 활용한 to do list
Date.now()함수를 이용해 겹치지 않는 id값과 함께 to do list text를 로컬스토리지에 저장한다.
로컬스토리지에 컨텐츠가 배열 형태로 저장되지 않아 JSON.stringify(toDos) 를 활용해 '배열 모양으로' 저장한다.
로컬스토리지에 배열'모양'의 string 형태로 저장된 컨텐츠를 JSON.parse(savedToDos)를 이용해 실제 배열로 불러와 프린트해준다.
const toDoForm = document.querySelector(".todo-form");
const toDoInput = toDoForm.querySelector("input");
const toDoList = document.querySelector(".todo-list");
const TODOS_KEY = "todos";
let toDos = [];
function saveToDos(){
localStorage.setItem(TODOS_KEY, JSON.stringify(toDos));
// JSON.stringify()를 이용해 배열 문자 형태로 localStorage에 저장
}
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");
li.appendChild(span);
span.innerText = newTodo.text;
const button = document.createElement("button");
button.type ="button";
button.innerText = "❎";
li.appendChild(button);
button.addEventListener("click", deleteToDo);
toDoList.appendChild(li);
}
function handleToDoSubmit(event){
event.preventDefault();
const newTodo = toDoInput.value;
toDoInput.value = "";
const newTodoObj = {
id : Date.now(),
text : newTodo,
};
console.log(toDos.length);
if(toDos.length < 7){
toDos.push(newTodoObj); // toDos Array에 Push
paintToDo(newTodoObj);
saveToDos();
} else {
alert("You can only enter up to 7.");
}
}
toDoForm.addEventListener("submit", handleToDoSubmit);
const savedToDos = localStorage.getItem(TODOS_KEY);
if(savedToDos){ // savedToDos가 없으면 null이 반환된다.(false) 있으면 true
const parsedToDos = JSON.parse(savedToDos); // 문자형태인 savedToDos를 array 형태로 반환
toDos = parsedToDos;
parsedToDos.forEach((item) => paintToDo(item));
// parsedToDos.forEach(paintTodo);
}
js/weather.js
https://api.openweathermap.org/
API를 사용하여 간단하게 날씨 정보를 출력할 수 있다.
const weatherIcon = {
"01": "fa-sun", // clear sky
"02": "fa-cloud-sun", // few clouds
"03": "fa-cloud", // scattered clouds
"04": "fa-cloud-meatball", // broken clouds
"09": "fa-cloud-rain", // shower rain
"10": "fa-cloud-showers-heavy", // rain
"11": "fa-cloud-bolt", // thunderstorm
"13": "fa-snowflake", // snow
"50": "fa-water", // mist
};
const API_KEY = "ab25b9205ac4992cdb13d1409a98f3d6";
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`;
// console.log(url);
fetch(url).then(response => response.json()).then(data =>{
// const weatherWrap = document.querySelector(".weather");
const icon = document.querySelector(".weather i");
const temp = document.querySelector(".weather span:nth-of-type(1)");
const weather = document.querySelector(".weather span:nth-of-type(2)");
const city = document.querySelector(".weather p");
const iconNum = (data.weather[0].icon).substr(0,2); // icon번호
const iconEmoji = weatherIcon[iconNum]; // 배열에서 fontawsome class 받아오기
icon.classList.add(iconEmoji) // 해당 클래스 +
temp.innerText = `${Math.floor(data.main.temp)}℃`;
weather.innerText = `${data.weather[0].main}`;
city.innerText = data.name;
});
// http://openweathermap.org/img/w/10d.png
}
function onGeoError(){
alert("Can't find you. No weather for you.");
}
navigator.geolocation.getCurrentPosition(onGeoOk, onGeoError);
'Study > JavaScript' 카테고리의 다른 글
Timer 타이머 (0) | 2022.05.18 |
---|---|
ES6 배열 내장 함수 (0) | 2022.04.26 |
React JS (0) | 2022.04.15 |
Vue JS (1) | 2022.04.08 |
Angular JS (0) | 2022.04.06 |