JS - [231202] LogIn / Clock / Quote실습

IRISH·2023년 12월 11일
0

JS

목록 보기
20/80
post-thumbnail

LogIn

설계

  • 로컬 스토리지에 LogIn 관련 키가 없을 경우
    • 로그인 Form이 보이게 한다.
    • 값 입력 후, Form의 Button을 클릭하면 로컬 스토리지에 LogIn 관련 키를 할당한다.
    • 로그인 Form을 사라지게 한다.
    • ID 기준으로 환영말을 보이게 한다.
  • 로컬 스토리지에 LogIn 관련 키가 있을 경우
    • 로그인 Form은 처음부터 안보이고, ID 기준으로 환영말만 보이게 한다.

소스 코드

style.css

body{
    background-color: aqua;
}

.hidden{
    display:none;
}

index.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="style.css">
    <title>vanillaJS</title>
</head>
<body>
    <form id = "login-form">
        <h3>Log In, Plz</h3>
        <input required maxlength="15" placeholder="ID를 입력하시오"/>
        <button>Log In</button>
    </form>

    <h1 id="greeting" class="hidden"></h1>

    <script src="app.js"></script>
</body>
</html>

app.js

const loginForm = document.querySelector("#login-form");
const loginInput = document.querySelector("#login-form input");
const greeting = document.querySelector("#greeting");

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

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 = `안녕하세요! ${username} 님!`;
    greeting.classList.remove(HIDDEN_CLASSNAME);
}

const savedUsername = localStorage.getItem(USERNAME_KEY);

// 로컬 스토리지에 값 없으면, 로그인 폼 보여주기
if (savedUsername === null) {
    loginForm.classList.remove(HIDDEN_CLASSNAME);
    loginForm.addEventListener("submit", onLoginSubmit);
} else { // 값 로컬 스토리지에 값 있으면, 로그인 폼 비활성화
    loginForm.classList.add(HIDDEN_CLASSNAME);
    paintGreetings(savedUsername);
}
  • preventDefault();
    • 새로고침 방지
  • classList
    • 클래스 추가 및 삭제
      • 추가 : classList.add()
      • 삭제 : classList.remove()
  • localStorage
    • 로컬스토리지
      • localstorage.getItem(키) : 키를 통해서 값 가져오기
      • localstorage.removeItem(키) : 키를 통해서 키 및 값 제거
      • localstorage.setItem(키, 값) : 키에 해당 값 할당

결과 화면

⇒ 초기 화면

⇒ ID 입력창에 입력 후 로그인 버튼 클릭했을 경우

  • 로컬 스토리지에 값이 잘 들어갔다
  • 로그인 폼 모양이 hidden 처리됐다.
  • 안녕 문구가 잘 보인다.

⇒ 새로 고침 시

  • 로컬 스토리지에 값이 있으므로 로그인 폼은 그대로 hidden 처리 상태이고, 안녕 문구가 계속 보인다.

Clock

설계

  • HH:MM:SS 형식으로 시간을 출력한다.

소스코드

css/style.css

body{
    background-color: aqua;
}

.hidden{
    display:none;
}

index.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>
    <form 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>
    <h2 id="clock">00:00:00</h2>
    
    <script src="js/greeting.js"></script>
    <script src="js/clock.js"></script>
  </body>
</html>

js/greeting.js

const loginForm = document.querySelector("#login-form");
const loginInput = document.querySelector("#login-form input");
const greeting = document.querySelector("#greeting");

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

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 = `안녕하세요! ${username} 님!`;
    greeting.classList.remove(HIDDEN_CLASSNAME);
}

const savedUsername = localStorage.getItem(USERNAME_KEY);

// 로컬 스토리지에 값 없으면, 로그인 폼 보여주기
if (savedUsername === null) {
    loginForm.classList.remove(HIDDEN_CLASSNAME);
    loginForm.addEventListener("submit", onLoginSubmit);
} else { // 값 로컬 스토리지에 값 있으면, 로그인 폼 비활성화
    loginForm.classList.add(HIDDEN_CLASSNAME);
    paintGreetings(savedUsername);
}

js/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);
  • Date() : 시간 관련 함수
    • getHours() / getMinustes() / getSeconds() 등
  • padStart() : 자릿수 맞추게 해주는 함수
  • setInterVale(값, 시간)
    • 시간 단위로 값을 처리

결과 화면


Quote

설계

  • css/style.css & js/greeting.js & js/clock.js 는 동일
  • index.html
    • “quote”란 id 값을 갖는 div 생성
    • “quote” Div에 span 태그 2개 할당
  • css/quotes.js
    • 명언과 명언을 작성한 저자 10개를 중점으로 객체를 구성한다.
    • 랜덤으로 명언 객체 10개 중 하나를 선별하여 화면에 띄운다.

소스 코드

index.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>
    <form 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>
    <h2 id="clock">00:00:00</h2>

    <div id="quote">
        <span></span> <br>
        <span></span>
    </div>
    
    <script src="js/greeting.js"></script>
    <script src="js/clock.js"></script>
    <script src="js/quotes.js"></script>
  </body>
</html>

js/quotes.js

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 spanQuote = document.querySelector("#quote span:first-child");
const spanAuthor = document.querySelector("#quote span:last-child");

const todaysQuote = quotes[Math.floor(Math.random() * quotes.length)];

spanQuote.innerText = "명언 = " + todaysQuote.quote;
spanAuthor.innerText = "저자 = " + todaysQuote.author;
  • Math.floor(Math.random() * quotes.length)
    • random 함수를 활용하여 난수 생성

결과 화면

ToDo List

설계

  • ToDo List 입력창에 list를 입력하면 해당 리스트를 화면에 차례대로 보여준다.
  • list를 로컬 스토리지에 저장 시켜 놓아서, 새로고침 등을 하더라도 저장되어 있던 lilst들을 보여준다.
  • 특정 list 삭제를 위해 각 리스트 우측에 있는 “X” 모양 버튼 클릭 시 해당 리스트 값을 화면과 로컬 스토리지에서 삭제한다.

소스 코드

  • 나머지 파일들은 동일

index.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>
    <form id="login-form">
      <input
        required
        maxlength="15"
        type="text"
        placeholder="What is your name?"
      />
      <input type="submit" value="Log In" />
    </form>
    
    <h2 id="clock">00:00:00</h2>
    <h1 id="greeting" class="hidden"></h1>

    <form id="todo-form">
        <input type="text" placeholder="Write a To Do and Press Enter" required />
    </form>
    <ul id="todo-list"></ul>

    <div id="quote">
        <span></span> <br>
        <span></span>
    </div>
    
    <script src="js/greeting.js"></script>
    <script src="js/clock.js"></script>
    <script src="js/quotes.js"></script>
    <script src="js/todo.js"></script>
  </body>
</html>

js/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";

// 새로고침 시 로컬 스토리지 값 Binding 위해 const가 아닌 let 활용
let toDos = [];

function saveToDos(){ // toDo 리스트들을 로컬 스토리지에 배열 형식으로 저장
    // (STRINGIFY = 변수 등을 문자열로 바꿈, PARSE = 문자열을 JSON으로 바꿈)
    localStorage.setItem(TODOS_KEY, JSON.stringify(toDos));
}

function deleteToDo(event){ // 특정 toDo를 삭제하는 함수
    const li = event.target.parentElement;
    li.remove();
    /*
    - toDo는 toDos DB에 있는 요소 중 하나!!!
    - li.id 는 삭제한 버튼 => 즉, 아래 filter() 역할 : 삭제한 id 외의 값들은 남긴다!
    - li.id는 문자열 / toDo.id는 정수 => 따라서, li.id를 parseInt()를 해준다! */
    toDos = toDos.filter(toDo => toDo.id !== parseInt(li.id)); 
    saveToDos(); // 한 번 더 저장!
}

function paintToDo(newTodo){ // toDo를 그리는 함수
    const li = document.createElement("li");
    li.id = newTodo.id;
    const span = document.createElement("span");
    // 파라미터인 newTodo가 객체이므로 글자를 보고 싶으면 text 메서드 사용
    span.innerText = newTodo.text;
    const button = document.createElement("button");
    button.innerText = "X";
    button.addEventListener("click", deleteToDo);
    li.appendChild(span); // HTML의 li 태그에 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에 기존 로컬 스토리지 값 넣어주기
  toDos = parsedToDos; 
  parsedToDos.forEach(paintToDo);
}

결과 화면

profile
#Software Engineer #IRISH

0개의 댓글