๋ณธ๋ฌธ ๋ฐ”๋กœ๊ฐ€๊ธฐ

javascript/๋ฐ”๋‹๋ผ JS๋กœ ํฌ๋กฌ ์•ฑ ๋งŒ๋“ค๊ธฐ

DAY 8

#4.4 Getting Username

 

 

submit ๋ฒ„ํŠผ์„ ํด๋ฆญํ–ˆ์„ ๋•Œ, form ์ž์ฒด๋ฅผ ์‚ฌ๋ผ์ง€๊ฒŒ ํ•˜๋Š” ๋ฐฉ๋ฒ•์ด 2๊ฐœ๊ฐ€ ์žˆ๋‹ค.

โ‘  form ํƒœ๊ทธ ์ž์ฒด๋ฅผ ์ œ๊ฑฐํ•˜๋Š” ๊ฒƒ

โ‘ก css์—์„œ display:none; ์†์„ฑ์„ ์ถ”๊ฐ€ํ•ด์ฃผ๋Š” ๊ฒƒ

 

 

์•„๋ž˜๋Š” form์—์„œ ์ž…๋ ฅ๊ฐ’์„ ๋ฐ›์•„์˜ค๋ฉด form์€ ์ œ๊ฑฐํ•˜๊ณ , ๋ฐ›์•„์˜จ ์ž…๋ ฅ๊ฐ’์„ ์ถœ๋ ฅํ•˜๋Š” ์ฝ”๋“œ๋‹ค.

 

 index.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" />
    <title>Momentum</title>
    <link rel="stylesheet" href="style.css" />
  </head>
  <body>
    <form id="login-form">
      <input required maxlength="15" type="text" placeholder="What is your name?" />
      <input type="submit" value="Login"/>
    </form>
    <h1 id="greeting" class="hidden"></h1>
    <script src="app.js"></script>
  </body>
</html>

login-form์—์„œ ์ž…๋ ฅ๊ฐ’์„ ๋ฐ›์•„์˜ค๋ฉด form ํƒœ๊ทธ๋Š” ์•„์˜ˆ ์‚ฌ๋ผ์งˆ ๊ฒƒ์ด๊ณ , h1 ํƒœ๊ทธ๊ฐ€ ๋ณด์—ฌ์ง€๊ฒŒ ๋  ๊ฒƒ์ด๋‹ค. 

 

 

 

 style.css ์—๋Š” ๋‹ค์Œ๊ณผ ๊ฐ™์€ ํด๋ž˜์Šค๋ฅผ ๋งŒ๋“ค์—ˆ๋‹ค.

.hidden{
   display:none;
}
/* ์ข€ ๋น„์Šทํ•œ ์†์„ฑ์—๋Š” display:hidden;์ด ์žˆ์ง€๋งŒ, ์ด๋Š” ๊ทธ๋ƒฅ ๋ณด์ด์ง€ ์•Š๊ฒŒ ์ˆจ๊ฒจ์ฃผ๋Š” ๊ฒƒ ๋ฟ
ํ•ด๋‹น ์š”์†Œ๊ฐ€ ์ฐจ์ง€ํ•˜๋Š” ๊ณต๊ฐ„๋„ ๊ทธ๋Œ€๋กœ์ด๋ฉฐ ๋”ฐ๋ผ์„œ html์—์„œ ์™„์ „ํžˆ ์ œ๊ฑฐ๋œ๊ฒŒ ์•„๋‹ˆ๋‹ค. */

 

 app.js ์—์„œ form์— ์ž‘์„ฑํ•œ ๊ฐ’์„ ๋ณ€์ˆ˜์— ๋‹ด๊ณ , loginForm์— ์ด ํด๋ž˜์Šค๋ฅผ ์ถ”๊ฐ€ํ•ด์ค„ ๊ฒƒ์ด๋‹ค. 

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

// ์ผ๋ฐ˜์ ์œผ๋กœ string๋งŒ ํฌํ•จ๋˜์–ด ์žˆ๊ณ , ๊ทธ๋ ‡๊ฒŒ ์ค‘์š”ํ•˜์ง€ ์•Š์€ ๋ณ€์ˆ˜๋Š” ๋Œ€๋ฌธ์ž๋กœ ํ‘œ๊ธฐํ•œ๋‹ค. 
// ๋ฌธ์ž์—ด์˜ ์˜คํƒ€๋Š” javascript๊ฐ€ ๋ฌด์‹œํ•˜์ง€๋งŒ, ๋ณ€์ˆ˜๋ช…์˜ ์˜คํƒ€๋Š” ์ง€์ ํ•ด์ฃผ๊ธฐ ๋•Œ๋ฌธ์—
// 2๋ฒˆ ์ด์ƒ ์‚ฌ์šฉ๋˜๋Š” ๊ฒฝ์šฐ ์ด๋ ‡๊ฒŒ ๋ณ€์ˆ˜์— ๋‹ด๋Š” ๊ฒƒ์„ ์ถ”์ฒœํ•œ๋‹ค.
const HIDDEN_CLASSNAME = "hidden";

function onLoginSubmit(event){
  // submit ๋ฒ„ํŠผ ํด๋ฆญ ์‹œ ์ž๋™์œผ๋กœ ์ƒˆ๋กœ๊ณ ์นจ๋˜์–ด ์ •๋ณด๊ฐ€ ๋‚ ์•„๊ฐ€๋Š” ๊ฒƒ์„ ๋ฐฉ์ง€
  event.preventDefault();
  const username = loginInput.value;
  // loginForm์„ ์ œ๊ฑฐํ•œ๋‹ค.
  loginForm.classList.add(HIDDEN_CLASSNAME);
  // h1 ํƒœ๊ทธ์— ์žˆ๋˜ hidden ํƒœ๊ทธ๋ฅผ ์ง€์›€์œผ๋กœ์จ ๋ณด์—ฌ์ง€๊ฒŒ ํ•œ๋‹ค.
  greeting.classList.remove(HIDDEN_CLASSNAME);
  // h1 ํƒœ๊ทธ ์•ˆ์— hello + username์„ ์ถœ๋ ฅํ•œ๋‹ค.
  greeting.innerText = `Hello ${username}`;
}

loginForm.addEventListener("submit", onLoginSubmit);

 

 

#4.5 Saving Username

 

๋ฌด์–ธ๊ฐ€๋ฅผ ์ €์žฅํ•˜๋Š” ๊ฒƒ์€ ๋งค์šฐ ์ž์ฃผ ์‚ฌ์šฉ๋˜๋Š” ๊ธฐ๋Šฅ์ด๋‹ค. ์œ ํŠœ๋ธŒ์˜ ๋ณผ๋ฅจ์„ ์กฐ์ ˆํ•˜๊ณ  ์ƒˆ๋กœ๊ณ ์นจํ–ˆ์„ ๋•Œ ๊ทธ ์„ค์ •์ด ์œ ์ง€๋˜๋Š” ๊ฒƒ์ด ์ด์— ํ•ด๋‹นํ•œ๋‹ค. ์œ„์˜ ์ฝ”๋“œ์—์„œ๋Š” user๋ฅผ ์ €์žฅํ•ด๋‘๋Š” ๊ธฐ๋Šฅ์„ ๊ตฌํ˜„ํ•  ๊ฒƒ์ด๋‹ค.

 

๊ทธ ๊ธฐ๋Šฅ์„ ์ œ๊ณตํ•˜๋Š” API๊ฐ€ localStorage๋‹ค.

https://developer.mozilla.org/en-US/docs/Web/API/Window/localStorage 

localStorage์— ๋“ค์–ด์žˆ๋Š” ๊ฒƒ์„ ๋ณด๊ณ ์‹ถ๋‹ค๋ฉด ๊ฐœ๋ฐœ์ž ๋„๊ตฌ - Application - Storage - Local Storage์—์„œ ํ™•์ธํ•˜๋ฉด ๋œ๋‹ค. Storage์—๋Š” Session, indexedDB, WebSQL, ์ฟ ํ‚ค, Token ๋“ฑ๋„ ํ™•์ธํ•  ์ˆ˜ ์žˆ๋‹ค.

 

- setItem() : local storage์— ์ •๋ณด ์ €์žฅ 

- getItem() : local storage์— ์ €์žฅํ•œ ๊ฐ’์„ ๋ถˆ๋Ÿฌ์˜ด

- removeItem() : local storage์— ์ €์žฅํ•œ ๊ฐ’์„ ์‚ญ์ œ

 

local storage์—๋Š” ์˜ค๋ฅธ์ชฝ ์บก์ณ์™€ ๊ฐ™์ด key, value ํ˜•์‹์œผ๋กœ ์ €์žฅ๋œ๋‹ค.

 

localStorage.setItem("username", "hayeon");
localStorage.getItem("username");
localStorage.removeItem("username");

 

 

#4.6 Loading Username 

 

์ด์ œ local storage๋ฅผ ์ด์šฉํ•ด username์— ๊ด€ํ•œ ๊ธฐ๋Šฅ์„ ๊ตฌํ˜„ํ•œ๋‹ค.

 

1) ๋จผ์ € onLoginSubmit ํ•จ์ˆ˜์— localStorage์— username์„ ์ €์žฅํ•œ๋‹ค.

function onLoginSubmit(event){
// ์ค‘๋žต
  localStorage.setItem(USERNAME_KEY, username);
}

 

2) addEventListener๋ฅผ ํ•˜๊ธฐ ์ „์— ํ™•์ธํ•œ๋‹ค.

const savedUsername = localStorage.getItem(USERNAME_KEY);

if(savedUsername === null){
} else {
}

    (1) local storage๊ฐ€ ๋น„์–ด ์žˆ์œผ๋ฉด form์„ ๋ณด์—ฌ์ฃผ๋ฉด์„œ ์ดˆ๊ธฐํ™”ํ•œ๋‹ค. 

๊ทธ๋Ÿฌ๋‚˜ ์ง€๊ธˆ์˜ ์ฝ”๋“œ๋กœ๋Š” ์œ„์˜ if-else ๊ตฌ๋ฌธ๊ณผ ๊ด€๊ณ„์—†์ด form ํƒœ๊ทธ๊ฐ€ ๋ฌด์กฐ๊ฑด ๋ณด์—ฌ์ง€๋ฏ€๋กœ, index.html์—์„œ form ํƒœ๊ทธ์—๋„ class="hidden"์„ ์ถ”๊ฐ€ํ•œ๋‹ค.

// ์ด if๊ตฌ๋ฌธ๊ณผ ๊ด€๊ณ„์—†์ด form์ด ํ‘œ์‹œ๋˜๋ฏ€๋กœ form์—๋„ hidden ํด๋ž˜์Šค ์ถ”๊ฐ€ 
if(savedUsername === null){
  // show the form
  // ๋งŒ์•ฝ local storage์— ์ €์žฅ๋œ ๊ฐ’์ด ์—†๋‹ค๋ฉด, form ํƒœ๊ทธ์˜ hidden ํด๋ž˜์Šค ์ œ๊ฑฐ
  loginForm.classList.remove(HIDDEN_CLASSNAME);
  // 
  loginForm.addEventListener("submit", onLoginSubmit);
}

    (2) local storage์— ์œ ์ € ์ •๋ณด๊ฐ€ ์žˆ๋‹ค๋ฉด form์„ ์ง€์šฐ๊ณ  h1 ํƒœ๊ทธ๋ฅผ ๋ณด์—ฌ์ค˜์•ผ ํ•œ๋‹ค.

else {
  // show the greeting
  // ๋งŒ์•ฝ local storage์— ์ €์žฅ๋œ ๊ฐ’์ด ์žˆ๋‹ค๋ฉด, #greeting์˜ hidden ํด๋ž˜์Šค ์ œ๊ฑฐ
  greeting.classList.remove(HIDDEN_CLASSNAME);
  // username์ด ์•„๋‹ˆ๋ผ savedUsername์ธ ์ด์œ ๋Š”
  // ์ด ๊ตฌ๋ฌธ์—๋Š” username์ด ์—†๊ธฐ ๋•Œ๋ฌธ์—(username์€ onLoginSubmit ํ•จ์ˆ˜ ์•ˆ์—์„œ๋งŒ ์กด์žฌํ•จ)
  // username ๊ฐ’์ด ๋Œ€์ž…๋œ USERNAME_KEY๋ฅผ ๋ฐ›์•„์˜จ savedUsername์„ ๋Œ€์‹  ์‚ฌ์šฉํ•จ.
  greeting.innerText = `Hello ${savedUsername}`; 
}

 

์œ„์ฒ˜๋Ÿผ ์ž‘์„ฑํ•œ ์ฝ”๋“œ์—๋Š” greeting.classList~์™€ greeting.innerText~ ์ด ๋‘ ์ค„์ด ๋ฐ˜๋ณต๋˜๋Š”๋ฐ, ๋‹ค์Œ๊ณผ ๊ฐ™์ด ์ƒˆ๋กœ์šด ํ•จ์ˆ˜๋ฅผ ๋งŒ๋“ค์–ด ์ด ๋ถ€๋ถ„์˜ ์ค‘๋ณต์„ ์ค„์ธ๋‹ค.

function paintGreetings(username){
  // ์—ฌ๊ธฐ์—์„œ์˜ username์€ ๋‹จ์ง€ ์ธ์ž์ผ ๋ฟ์ด๋ฏ€๋กœ tomato, aibao ๋“ฑ๋“ฑ ์•„๋ฌด๊ฑฐ๋‚˜ ํ•ด๋„ ์ƒ๊ด€์—†๋‹ค..
  greeting.innerText = `Hello ${username}`; 
  greeting.classList.remove(HIDDEN_CLASSNAME);
}

 

 

 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 = `Hello ${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 {
  paintGreetings(savedUsername);
}
console.log(savedUsername);

 

 

#6.0 Quotes

 

์ฝ”๋“œ ์ฑŒ๋ฆฐ์ง€๋ฅผ ํ•  ๋•Œ ์ฐธ๊ณ ํ•ด์•ผ ํ•œ๋‹ค๊ณ  ํ•ด์„œ ์—ฌ๊ธฐ๋‹ค๊ฐ€ ์ •๋ฆฌ

 

index.html, quotes.js : https://github.com/nomadcoders/javascript-for-beginners/commit/0c6d246bd1fc5e3a4a55ef00aa08fd1b9420ce94

clock.js : https://github.com/nomadcoders/javascript-for-beginners/blob/master/js/clock.js

greeting.js : https://github.com/nomadcoders/javascript-for-beginners/blob/a3a25c939aea604f071cebcaab3e3895c91f5dbe/js/greetings.js

style.css๋Š” ์œ„์™€ ๊ฐ™์Œ

 

(์ •์ž‘ ์ด ๊ฐ•์˜ ์‹ค์Šต์—๋Š” index.html๊ณผ quotes.js๋งŒ ์“ฐ๊ธด ํ•œ๋‹ค.)

 

 

index.html

  <body>
    <form class="hidden" 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 class="hidden" id="greeting"></h1>
    <div id="quote">
      <span></span>
      <span></span>
    </div>
    <script src="js/greetings.js"></script>
    <script src="js/clock.js"></script>
    <script src="js/quotes.js"></script>
  </body>

id๊ฐ€ quote์ธ divํƒœ๊ทธ ๋‚ด์˜ spanํƒœ๊ทธ๋Š” ๋ช…์–ธ๊ณผ ์ž‘๊ฐ€๊ฐ€ ๊ฐ๊ฐ ๋‹ด๊ธธ ๊ฒƒ์ด๋‹ค.

 

quotes.js

const quotes = [
	// ๋ช…์–ธ๋“ค
];

const quote = document.querySelector("#quote span:first-child");
const author = document.querySelector("#quote span:last-child");
const todaysQuote = quotes[Math.floor(Math.random() * quotes.length)];

quote.innerText = todaysQuote.quote;
author.innerText = todaysQuote.author;

 

์ด์ œ ๋ช…์–ธ์€ #quote์˜ ์ฒซ๋ฒˆ์งธ span ํƒœ๊ทธ๋ฅผ, ์ž‘๊ฐ€์—๋Š” ๋งˆ์ง€๋ง‰ span ํƒœ๊ทธ๋ฅผ ๊ฐ€์ ธ์™”๋‹ค.

์ด ๋•Œ ๋ช…์–ธ array์˜ ๋ชจ๋“  ์˜ค๋ธŒ์ ํŠธ๋ฅผ ๊ฐ€์ ธ์˜ค๊ธฐ ์œ„ํ•ด์„œ๋Š” quotes[0] ๋ถ€ํ„ฐ [9]๊นŒ์ง€ ๊ฐ€์ ธ์™€์•ผ ํ•˜๋Š”๋ฐ, ์ด๋Š” math module์— ์žˆ๋Š” ํ•จ์ˆ˜๋ฅผ ์‚ฌ์šฉํ•˜๋ฉด ๋œ๋‹ค.

 

๊ทธ ์ค‘ Math.random()์€ 0๋ถ€ํ„ฐ 1 ์‚ฌ์ด์˜ ๋žœ๋คํ•œ ์ˆซ์ž๋ฅผ ์ œ๊ณตํ•˜๋Š”๋ฐ, 0~9๊นŒ์ง€์˜ ์ˆซ์ž๊ฐ€ ํ•„์š”ํ•˜๋ฏ€๋กœ quotes.length๋ฅผ ๊ณฑํ•ด์ฃผ๋ฉด 0๋ถ€ํ„ฐ 10๋ฏธ๋งŒ์˜ ์ˆซ์ž๋ฅผ ์ œ๊ณตํ•ด์ค„ ๊ฒƒ์ด๋‹ค. 

๊ทธ๋ฆฌ๊ณ  ๋’ค์˜ ์†Œ์ˆ˜๋ถ€๋ถ„์„ ์ „๋ถ€ ๋นผ์ค„ ํ•จ์ˆ˜ ์„ธ ๊ฐœ๋„ ์กด์žฌํ•œ๋‹ค.

Math.floor()์€ ์†Œ์ˆ˜์ ์„ ๋ฒ„๋ฆฌ๊ธฐ ๋•Œ๋ฌธ์— [0]~[n-1]๊นŒ์ง€,

Math.ceil()์€ ์†Œ์ˆ˜์ ์„ ์˜ฌ๋ฆฌ๊ธฐ ๋•Œ๋ฌธ์— [1]~[n]๊นŒ์ง€,

Math.round()๋Š” ์†Œ์ˆ˜์ ์„ ๋ฐ˜์˜ฌ๋ฆผํ•˜๊ธฐ ๋•Œ๋ฌธ์— [0]~[n]๊นŒ์ง€ ๋‚˜์˜จ๋‹ค.

 

์šฐ๋ฆฌ๋Š” 0~9๊นŒ์ง€์˜ ์ •์ˆ˜๋ฅผ ์–ป๊ณ  ์‹ถ์œผ๋ฏ€๋กœ floor()์„ ์ด์šฉํ•œ๋‹ค. (๋งŒ์•ฝ ceil์ด๋‚˜ round๋ฅผ ์ด์šฉํ•˜๊ฒŒ๋˜๋ฉด Math.random() * quotes.length์˜ ๊ฐ’์ด 9.***๊ฐ€ ๋‚˜์™”์„ ๋•Œ ceil์€ ๋ฌด์กฐ๊ฑด 10์„, round๋„ ๊ทธ ์ˆ˜์— ๋”ฐ๋ผ 10์„ ์ถœ๋ ฅํ•  ์ˆ˜๋„ ์žˆ์œผ๋ฉฐ, ๊ฐ’์ด 0.****๊ฐ€ ๋‚˜์˜ค๋ฉด ๋งˆ์ฐฌ๊ฐ€์ง€๋กœ ceil์€ ๋ฌด์กฐ๊ฑด 1์„, round๋„ 1์„ ์ถœ๋ ฅํ•  ์ˆ˜๋„ ์žˆ๊ธฐ ๋•Œ๋ฌธ์— floor()์„ ์‚ฌ์šฉํ•œ๋‹ค.)

 

๊ทธ๋ฆฌ๊ณ  innerText๋กœ todaysQuote์˜ quote์™€ author๋ฅผ ๊ฐ๊ฐ ๋‹ด๋Š”๋‹ค. 

 

'javascript > ๋ฐ”๋‹๋ผ JS๋กœ ํฌ๋กฌ ์•ฑ ๋งŒ๋“ค๊ธฐ' ์นดํ…Œ๊ณ ๋ฆฌ์˜ ๋‹ค๋ฅธ ๊ธ€

DAY 11  (0) 2023.01.05
DAY 10  (0) 2023.01.04
DAY 5  (0) 2022.12.30
DAY 4  (0) 2022.12.30
DAY 3  (0) 2022.12.28