javascript

Vanilla JS - momentum 클론코딩

May 31, 2020

vanilla.js - 2

크롬앱 momentum 클론코딩

  1. Clock
  2. Save user name
  3. Todo list
  4. Image background
  5. weather

1. clock

index.html

<!DOCTYPE html>
<html>
  <head>
    <meta charset="utf-8">
    <meta name="viewport" content="width=device-width">
    <title>javascript Test</title>
    <link href="index.css" rel="stylesheet" type="text/css" />
  </head>
  <body>
    <div class="js-clock">
      <h1>00:00</h1>
    </div>
    <script src="clock.js"></script>
  </body>
</html>

clock.js

const clockContainer = document.querySelector(".js-clock");
const clockTitle = clockContainer.querySelector("h1");

function getTime() {
    const date = new Date();
    let 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() {
    setInterval(getTime, 1000);
}

init();



2. save user name

<!DOCTYPE html>
<html>
  <head>
    <meta charset="utf-8">
    <meta name="viewport" content="width=device-width">
    <title>javascript Test</title>
    <link href="index.css" rel="stylesheet" type="text/css" />
  </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>

    <script src="clock.js"></script>
    <script src="greeting.js"></script>
  </body>
</html>
body{
    background-color: #ecf0f1;
}
  
.btn {
    cursor: pointer;
}

h1{
    color: #34495e;
    transition: color 0.5s ease-in-out;
}

.clicked {
    color: #7f8c8d;
}

.form,
.greetings { 
    display: none;
}

.showing {
    display: block;
}
const form  = document.querySelector(".js-form");
const input = form.querySelector("input");
const greeting = document.querySelector(".js-greetings");

const USER_LOCAL_STORAGE = "currentUser";
const SHOWING_CLASSNAME = "showing";


function saveName(name) {
    localStorage.setItem(USER_LOCAL_STORAGE, name);
}

function handleSubmit(event) {
    event.preventDefault();
    const currentValue = input.value;
    paintGreeting(currentValue);
    saveName(currentValue);
}

function askForName() {
    form.classList.add(SHOWING_CLASSNAME);
    form.addEventListener("submit", handleSubmit);
}

function paintGreeting(text) {
    form.classList.remove(SHOWING_CLASSNAME);
    greeting.classList.add(SHOWING_CLASSNAME);
    greeting.innerText = `Hello ${text}`;
}

function loadName() {
    const currentUser = localStorage.getItem(USER_LOCAL_STORAGE);
    if(currentUser === null) {
        askForName();
    } else {
        paintGreeting(currentUser);
    }
}

function init() {
    loadName();
}

init();



3. to do list

index.html

<!DOCTYPE html>
<html>
  <head>
    <meta charset="utf-8">
    <meta name="viewport" content="width=device-width">
    <title>javascript Test</title>
    <link href="index.css" rel="stylesheet" type="text/css" />
  </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>

    <script src="clock.js"></script>
    <script src="greeting.js"></script>
    <script src="todo.js"></script>
  </body>
</html>

todo.js

const toDoForm = document.querySelector(".js-toDoForm");
const toDoInput = toDoForm.querySelector("input")
const toDoList = document.querySelector(".js-toDoList");

const TODOS_LOCAL_STORAGE = "toDos";

let toDos = [];

function deleteToDo(event) {
    // 해당 이벤트를 호출하는 삭제 버튼의 부모를 찾아서 
    // 자식노드인 li를 삭제한다.
    // filter 메서드를 이용해 삭제된 toDo를 제외시킨다.
    const btn = event.target;
    const li = btn.parentNode;
    toDoList.removeChild(li);
    const cleanToDos = toDos.filter(function(toDo) {
        // li의 id는 문자열이므로 숫자로 바꾼다.
        return toDo.id !== parseInt(li.id);
    });

    // toDos를 변경하기 위해 const에서 let으로 변경한다.
    toDos = cleanToDos;
    saveToDos();
}

function saveToDos() {
    // 로컬스토리지에 객체를 바로 저장하면 'object Object' 처럼 저장이 되므로
    // JSON.stringify(object)를 사용해서 객체를 문자열로 저장한다.
    localStorage.setItem(TODOS_LOCAL_STORAGE, JSON.stringify(toDos));
}


function paintToDo(text) { 
    // li를 만들어 todoList에 넣는다.
    const li = document.createElement("li");
    const delBtn = document.createElement("button");
    delBtn.innerHTML  = "❌"; // 이모지
    delBtn.addEventListener("click", deleteToDo);
    const span = document.createElement("span");
    // 새로 생성한 li에 id를 넣는다.
    const newId = toDos.length + 1
    span.innerText = text;
    li.appendChild(delBtn);
    li.appendChild(span);
    li.id = newId;
    toDoList.appendChild(li);
    // 객체를 toDos 배열에 넣는다.
    const toDoObj = {
        text: text,
        id: newId
    };
    toDos.push(toDoObj);
    saveToDos();
}
 
function handleSubmit(event) {
    // 이벤트를 막음. 여기서는 from submit 되어 리프레시되는 것을 막는다.
    event.preventDefault();
    const currentValue = toDoInput.value;
    paintToDo(currentValue);
    toDoInput.value = ""
}

function loadToDos() {
    // localStorage에 있는 todo 리스트를 가져온다.
    const loadedTodos = localStorage.getItem(TODOS_LOCAL_STORAGE);
    if(loadedTodos !== null) {
        const parsedToDos = JSON.parse(loadedTodos);
        parsedToDos.forEach(function(toDo) {
            // todo 리스트가 있으면 화면에 출력한다.
            paintToDo(toDo.text);
        });
    }
}

function init() {
    loadToDos(); 
    toDoForm.addEventListener("submit", handleSubmit);
}

init();



4. image background

index.css

@keyframes fadeIn {
    from {
        opacity: 0;
    }
    to {
        opacity: 1;
    }
}

.bgImage {
    position: absolute;
    top: 0;
    left: 0;
    width: 100%;
    height: 100%;
    z-index: -1;
    animation: fadeIn .5s linear;
}

bg.js

const body = document.querySelector("body");

function printImage(imgNumber) {
    const image = new Image();
    image.src = `images/${imgNumber + 1}.jpg`;
    image.classList.add("bgImage");
    body.prepend(image);
}

function getRandom() {
    const number = Math.floor(Math.random() * 5);
    return number;
}

function init() {
    const randomNumber = getRandom();
    printImage(randomNumber);
}

init();



5. Weather

https://openweathermap.org API 사용

weather.js

const weather = document.querySelector(".js-weather");

const API_KEY = "xxxxxxxx";
const COORDS = "coords";

function getWeather(lat, lon) {
    fetch(
        `https://api.openweathermap.org/data/2.5/weather?lat=${lat}&lon=${lon}&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} @ ${place}`;
    });
}

function saveCoords(coordObj) {
    localStorage.setItem(COORDS, JSON.stringify(coordObj));
}

function handleGeoSuccess(position) {
    const latitude = position.coords.latitude;
    const longitude = position.coords.longitude;
    const coordsObj = {
        latitude,  // key, value가 같으면 하나만 써도 된다.
        longitude
    };
    saveCoords(coordsObj);
    getWeather(latitude, longitude);
}

function handleGeoError() {
    console.log("Can't access geo location");
}

function askforCoords() {
    // navigator
    navigator.geolocation.getCurrentPosition(handleGeoSuccess, handleGeoError)
}
 
function loadCoords() {
     const loadedCoords = localStorage.getItem(COORDS);
     if(loadedCoords === null) {
         askforCoords();
     } else {
         const parsedCoords = JSON.parse(loadedCoords);
         console.log(parsedCoords);
         getWeather(parsedCoords.latitude, parsedCoords.longitude);
     }
}

function init() {
    loadCoords();
}

init();