📌 Login을 구현해보자 - 입력
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>Momentum App</title>
</head>
<body>
<div id="login-form">
<input type="text" placeholder="What is your name?" />
<button>Log In</button>
</div>
<script src="app.js"></script>
</body>
</html>
HTML 내에 id="login-form"을 가진 div를 만들고 그 아래 input과 button을 만들어준다.
이를 JS에서 찾아내보자.
JS
const loginform = document.getElementById("login-form");
const loginInput = loginform.querySelector("input");
const loginButton = loginform.querySelector("button");
document에서 id="login-form"를 찾고, 그 아래에 있는 input, button을 찾아낸다.
const loginInput = document.querySelector("#login-form input");
const loginButton = document.querySelector("#login-form button");
다른 방식으로는 querySelector를 사용해서 찾을 수 있다.
단 이렇게 하면 login-form이 id라는 걸 알려줘야해서 CSS처럼 #을 붙여줘야 한다.
버튼을 눌렀을 때 이벤트가 발동되게 하기 위해 addEventListener를 사용한다.
function onLoginBtnClick() {
console.log("click!!!!!");
}
loginButton.addEventListener("click", onLoginBtnClick);
지금 나는 login-form input에 이름을 입력하고 버튼을 누르면 인사와 함께 내 이름을 말해주는 기능을 구현하고 싶다.
function onLoginBtnClick() {
console.log("hello", loginInput.value); #hello 누구누구 출력 원함
}
그렇다면 이렇게 function을 구축하면 hello + loginInput.value(내 이름)이 출력된다.
하지만 loginInput에 아무 것도 입력하지 않으면 hello + 공백으로 뜨기에 이 부분을 좀 더 디테일하게 잡아주고자 한다.
버튼을 눌렀을 때 loginInput에 있는 value가 공백이거나 너무 길다면 어떻게 할까?
수업에서는 얼럿을 띄우기로 했다.
function onLoginBtnClick() {
const username = loginInput.value;
if (username === "") {
alert("Please write your name!");
} else if (username.length > 15) {
alert("Your name is too long.")
}
}
loginInput.value를 username으로 선언했다.
username이 공백일 경우에는 이름을 입력하라는 얼럿을, username가 15자를 넘을 경우에도 이름이 길다는 얼럿이 뜬다.
지금 우리는 JS에서 이런 얼럿을 띄움으로서 디테일을 잡아주었는데, 할 수 있다면 HTML의 기본 속성을 최대한 이용하는 것이 좋다고 한다. HTML에서도 공백으로 제출하지 못하게 하거나, 최대 길이를 정해놓을 수가 있다!
HTML
<body>
<form id="login-form">
<input
required
maxlength="15"
type="text" placeholder="What is your name?"
/>
<input type="submit" value="Log in" />
</form>
반드시 입력해야 한다는 'required'와 최대 길이 'maxlength'를 지정해두었다.
그리고 placeholder는 그 빈칸에 뭘 적을지 알려주는 일종의 커버 같은 속성이다.
input sumbit에 있는 value도 버튼의 커버 같은 속성이다.
📌 Login을 구현해보자 - 이벤트
입력을 했다면 이제 제출을 해보자.
JS
const loginForm = document.querySelector("#login-form");
const loginInput = document.querySelector("#login-form input");
function onLoginSubmit() {
const username = loginInput.value;
console.log(username);
}
loginForm.addEventListener("submit", onLoginSubmit);
submit할 경우 onLoginSubmit 함수가 작동해 console에 username이 표시된다.
그런데 제출을 하면 계속 새로고침이 된다.
이는 form submit의 기본 특성인데, 이렇게 되면 자꾸 제로가 된다.
이 기본 특성을 막아주기 위해 변수.preventDefault()를 사용한다.
어떤 event의 기본 행동이든 발생하지 않도록 해주는 함수로 아래와 같이 사용된다.
function onLoginSubmit(event) {
event.preventDefault();
console.log(loginInput);
}
form에서 발생한 submit event 관련 정보를 담을 용도로 해당 함수에 event라는 매개변수를 추가한다.
이 event는 기본동작(새로고침)이 prevent된 상태다.
📌 Login을 구현해보자 - 제출한 후에는
폼을 입력하고 제출한 후에는 더 이상 입력받지 않기 위해 폼을 숨겨주고 싶다.
HTML을 날리거나 CSS로 숨길 수 있는데 수업에서는 후자의 방식을 택했다.
HTML
<h1 id="greeting" class="hidden"></h1>
HTML의 h1에 hidden이라는 class를 부여한다.
CSS
.hidden {
display: none;
}
그리고 CSS에서 display 속성을 none으로 바꿔주어 숨겨주면 된다.
제출 > hidden class 숨기기 를 하기 위해서는 JS에서 function을 써준다.
JS
const greeting = document.querySelector("#greeting");
const HIDDEN_CLASSNAME = "hidden"
function onLoginSubmit(event) {
event.preventDefault();
loginForm.classList.add(HIDDEN_CLASSNAME);
const username = loginInput.value;
greeting.innerText = "Hello " + username; # `Hello ${username}` 과 같음
greeting.classList.remove(HIDDEN_CLASSNAME);
}
기본 동작(새로고침)은 실행되지 않게 prevent해주고, hidden class를 더해줘서 form을 숨긴다.
그리고 입력된 유저의 이름은 변수로 저장하고, 그 이름을 innerText에 넣어주면 된다.
여기서 배운 게 파이썬의 f string처럼 JS에서는 백틱과 ${} 을 활용해서 함께 출력해줄 수 있다.
📌 Login을 구현해보자 - 정보 저장
LocalStorage를 활용해서 value를 저장한다.
이놈은 브라우저에 뭔가를 기억할 수 있게 해주는 기능이다.
- localstorage.setitem(”username”, “summermong”) → 내 이름 저장
- localstorage.getitem(”username”) → 내 이름 불러오기
- localstorage.removeitem(”username”) → 내 이름 지우기
이런 식으로 활용할 수 있다.
우리는 유저가 이름을 제출하면 그걸 저장해주고 싶다.
const username = loginInput.value;
localStorage.setItem("username", username);
하지만 여전히 새로고침을 하면 방금까지 인사를 했던 페이지가 리셋된다.
즉 제출한 그 당시만 저장이 되고 계속 저장이 되진 않는다는 거다.
HTML
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8">
<meta name="viewpoint" content="width=device-width, initial-scale=1.0">
<link rel="stylesheet" href="style.css">
<title> Momentum </title>
</head>
<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>
<h1 id="greeting" class="hidden"></h1>
<script src="app.js"></script>
</body>
</html>
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);
}
좀 길어졌는데 천천히 복습해보자.
먼저 hidden class와 username이 여기의 핵심이다.
1) onLoginSubmit
이벤트가 발생하면 새로고침을 저지해주고, loginForm에 hidden이라는 class를 더해준다. (form을 숨겨준다.)
loginInput에 username이 setItem으로 저장된다.
그럼 paintGreetings함수에서 username을 인수로 받아 작동한다.
2) paintGreetings
이 함수에서는 greeting(h1의 id)의 innerText를 인사 + username으로 보여준다.
3) 만약 storage에 유저의 이름이 없다면 hidden을 제거해서 (form을 보여준다) submit을 받고,
유저의 이름이 있다면 그 이름을 인수로 paintGreetings함수가 작동된다.
즉 이름 제출 > 폼 안 보이게 함 > 이름 저장 > 이름을 인수로 받아 인사
저장된 이름이 없다면? > 폼 보이게 함 > 이름 받기
이런 로직이라고 이해하면 된다.
그 과정에서 classList.remove / add & localStorage를 사용했다는 것이 이 정리의 핵심이다.
📌 7일차 과제 - 카지노 게임
2일이나 줬던 코드 챌린지인만큼 기존 코드 챌린지에 비해 약간 난이도가 높아졌다.
이 게임은 0부터 특정 숫자 안에서 내가 고른 숫자 == 컴퓨터가 고른 숫자가 같아야 이기는 게임이라는 것이다.
내가 고른 수가 더 크다고 이기는 게임이 아니다! 실수할 뻔 했다 ^^;
이렇게 구현하는데 50, 25를 적고 Play! 버튼을 누르면 컴퓨터가 고른 랜덤의 숫자와 내 숫자를 비교한다.
막상 만들고 나면 진짜 별거 아니네 ㅠㅠ 싶지만 상수 설정 때문에 코드가 상당히...... 현기증 나게 생겼다.
카지노게임의 킥은 컴퓨터가 뽑은 랜덤의 숫자다.
선행학습 하면 할 수 있는데, Math.ceil(Math.random() * [50이 들어있는 칸의 값] 을 해주면 된다.
Math.random은 0 이상 1 미만의 숫자를 출력해주기 때문에, 범위 숫자를 곱해줘야 정수가 된다.
ceil로 소수점 숫자를 올려주면 되고... floor를 쓰면 안되는 건가? 싶긴 했다. 니코 샘이 힌트로 ceil을 주셔서...
암튼 이렇게 쪼끔 복잡하지만 다양한 기능을 배워보았다.
'👋🏻 JavaScript > 💭 노마드코더 바닐라JS' 카테고리의 다른 글
[노마드코더 바닐라JS로 크롬 앱 만들기] #7.0 ~ #7.8 (0) | 2023.03.08 |
---|---|
[노마드코더 바닐라JS로 크롬 앱 만들기] #6.0 ~ #6.3 (0) | 2023.03.08 |
[노마드코더 바닐라JS로 크롬 앱 만들기] #5.0 ~ #5.3 (0) | 2023.03.08 |
[노마드코더 바닐라JS로 크롬 앱 만들기] #3.0 ~ #3.8 (0) | 2023.03.07 |
[노마드코더 바닐라JS로 크롬 앱 만들기] #1.4 ~ #2.16 (0) | 2023.03.06 |