Vanila JS

Junyoung·2024년 7월 15일

Front

목록 보기
1/2
post-thumbnail

JS의 학습을 하게되어 학습 과정을 남겨 보려고 합니다.

노마드 강의

"바닐라JS 챌린지" 강의로 노마드의 니콜라스 선생님의 강의입니다.

JS로 사용하는 front중 가장 기본인 vanila JS를 활용한 간단한 웹사이트 제작입니다.

결과물

아래와 같이

  1. 로그인(text 로그인)
  2. 시계
  3. 명언(랜덤 명언)
  4. 사진(랜덤 사진)
  5. 해야 할일
  6. 계절(API를 활용한 실시간 날씨)

HTML, CS, JS 세가지의 파일로 나눠서 구성했습니다.

브라우저에 세가지 파일을 해석할수 있는 컴파일러와 엔진이 존재한다.
개발자 모드에서 console에 JS 코드를 직접 typing 할 수 있는 이유이다.

CS와 JS 파일은 독립적으로 실행되지 않으며, HTML 파일과 같이 import 되어 사용된다.

  • HTML
<!DOCTYPE html>
<html lang="en">
  <head>
    <meta charset="UTF-8" />
    <meta name="viewport" content="width=device-width, initial-scale=1.0" />
    <link rel="stylesheet" href="css/style.css" />
    <title>Momentum App</title>
  </head>
  <body>
    <h2 id="clock">00:00:00</h2>
    <form class="hidden" id="login-form">
      <input
        required
        maxlength="15"
        type="text"
        placeholder="What is your name?"
      />
      <input type="submit" value="Log In" />
    </form>
    <h1 id="greeting" class="hidden"></h1>
    <form id="todo-form">
      <input type="text" placeholder="Write a To Do and Press Enter" required />
    </form>
    <ui id="todo-list">
      <!-- <li>
        <span>text</span>
        <button>X</button>
      </li> -->
    </ui>
    <div id="quote">
      <span></span>
      <span></span>
    </div>
    <div id="weather">
      <span></span>
      <span></span>
    </div>
    <script src="js/greetings.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>
  • CS
.hidden {
  display: none;
}

'link rel="stylesheet" href="css/style.css"'
HTML의 해당 링크를 통해서 CS 파일을 import 시킨다.

  • JS
    greetings.js
const loginForm = document.querySelector("#login-form");
const loginInput = loginForm.querySelector("input");
const loginButton = loginForm.querySelector("button");
const greeting = document.querySelector("#greeting");

const HIDDEN_CLASSNAME = "hidden";
const USERNAME_KEY = "username";

function onLoginSubmit(event) {
  event.preventDefault();
  const usernameThatTheUserWrote = loginInput.value;
  loginForm.classList.add(HIDDEN_CLASSNAME);
  localStorage.setItem(USERNAME_KEY, usernameThatTheUserWrote);
  paintGreetings();
}

function paintGreetings() {
  const username = localStorage.getItem(USERNAME_KEY);
  greeting.innerText = `Hello ${username}`;
  greeting.classList.remove(HIDDEN_CLASSNAME);
}

const savedUsername = localStorage.getItem(USERNAME_KEY);
console.log(savedUsername);

if (savedUsername == null) {
  // show the form
  loginForm.classList.remove(HIDDEN_CLASSNAME);
  loginForm.addEventListener("submit", onLoginSubmit);
} else {
  // show the greetings
  paintGreetings();
}
  1. querySelector를 통해서 css 문법으로 dom구조의 속성을 가져온다.
  2. localStorage를 이용해서 사용자의 text를 기억하고 반영한다.
  3. addEventListener를 이용하여 이벤트를 수신한다.
  4. classList를 이용하여 속성의 css를 가변적으로 변경한다.

clock.js

const clock = document.querySelector("h2#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);
// console.log(clock.innerText);
  1. new Date()를 이용하여 현재 시각을 가져온다.
  2. setInterval() 를 이용하여 1초에 한번씩 시간을 갱신시킨다.
  3. padStart(2, "0")를 이용하여 11:11:1 ->11:11:01 형식으로 바꾼다.

quotes.js

const quotes = [
  {
    quote: "The way to get started is to quit talking and begin doing.",
    author: "Walt Disney",
  },
  // ... 이하 생략
];

const quote = document.querySelector("#quote span:first-child");
const author = document.querySelector("#quote span:last-child");
// 내가 원하는 숫자를 곱하면 0~ 숫자까지 랜덤으로 나온다.
const todaysQuote = quotes[Math.floor(Math.random() * quotes.length)];

quote.innerText = todaysQuote.quote;
author.innerText = todaysQuote.author;
  1. quotes 배열에 명언을 담아서 랜덤으로 출력한다.
  2. innerText를 활용하여 html 요소의 text를 설정해준다.

quotes.js

const images = ["1.jpeg", "2.jpeg", "3.jpeg"];

const chosenImage = images[Math.floor(Math.random() * images.length)];

const bgImage = document.createElement("img");

bgImage.src = `img/${chosenImage}` ;

document.body.appendChild(bgImage);
  1. images 배열에 명언을 담아서 랜덤으로 배정한다.
  2. document.createElement("img") img 태그를 생성한다.
  3. bgImage.src = img/${chosenImage} 이미지 이름을 배정한다.
  4. document.body.appendChild(bgImage); body에 위에서 만든 html을 추가한다.

todo.js

const toDoForm = document.querySelector("#todo-form");
const toDoInput = document.querySelector("#todo-form input");
const toDoList = document.querySelector("#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) => parseInt(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 = "x";
  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 parseToDos = JSON.parse(savedToDos);
  toDos = parseToDos;
  parseToDos.forEach(paintToDo);
}
  1. 위에서 생성한 todo를 기준으로 LocalStorage에서 데이터를 저장해두고, 또 화면에 반영한다.
  2. toDo 리스트 추가
    • toDo 배열에 text를 추가한다. (handleToDoSubmit)
    • toDo 배열을 기준으로 화면에 text를 추가한다.
    • LocalStorage에 toDo를 최신화 해준다. (saveToDos)
  3. toDo 리스트 삭제
    • 객체의 id를 활용하여 화면의 text를 지운다.(deleteTodo)
    • filter를 활용하여 배열에 text를 삭제한다.
    • LocalStorage에 toDo를 최신화 해준다. (saveToDos)

weather.js

const WeatherForm = document.querySelector("#weather");
const Name = WeatherForm.querySelector("span:first-child");
const Weather = WeatherForm.querySelector("span:last-child");
function onGeoOk(position) {
  // console.log(position);
  const lat = position.coords.latitude;
  const lng = position.coords.longitude;
  const key = "";
  const url = `https://api.openweathermap.org/data/2.5/weather?lat=${lat}&lon=${lng}&appid=${key}&units=metric`;
  console.log(url);

  // URL을 부른다.
  fetch(url)
    .then((response) => response.json())
    .then((data) => {
      const name = data.name;
      const weather = data.weather[0].main;
      Name.innerText = name;
      Weather.innerText = weather;
    });
}
function onGeoError() {
  alert("찾을수 없습니다. 에러 !");
}
navigator.geolocation.getCurrentPosition(onGeoOk, onGeoError);
  1. fetch 를 활용하여 외부 API에 요청을 보낸다.
  2. response으로 받아온 응답 결과를 response.json() Json 타입으로 변경한다.

순수 JS인 vanilaJS를 활용하여 Dom을 조작하고, 화면의 구성했다.

JQuery, framework 모두 이 순수 JS를 기반으로 동작하기에 중요한 학습 포인트라고 생각한다.

다음 포스팅에서는 이 코드를 바탕으로 JQuery로 변경하여 구성해보겠습니다.

profile
라곰

0개의 댓글