LOGIN _ 노마드코더 _ 바닐라JS크롬앱만들기

라용·2022년 8월 4일
1

노마드코더 바닐라 JS로 크롬 앱 만들기 강의를 듣고 정리한 기록입니다. 아래 내용은 4.0 - 4.7 에 해당합니다.

4.0 Input Values

user 에게 질문하고 답변을 받아서 정보를 화면에 표시하는 기능을 만들어 봅니다. js 에는 정보를 기억하는 기능이 있습니다. 우선 html 을 작성합니다.

<div id="login-form">
	<input type="text" placeholder="What is your name?" />
	<button>Log In</button>
</div>

js 에서 inputbutton 을 불러와 선택합니다.

const loginInput = document.querySelector("#login-form input");
const loginButton = document.querySelector("#login-form button");

button 클릭을 감지하고 작동할 함수를 만들어 보면,

function onLoginBtnClick(){
	// 실행할 코드
}
loginButton.addEventListener("click", onLoginBtnClick);

console.dir(input) 이런 식으로 콘솔을 찍어보면 필요한 프로퍼티를 체크할 수 있습니다.

4.1 Form Submission

입력받는 username 이 비어있거나, 너무 길면 안되도록 유효성 검사를 한다면, 아래와 같이 조건문을 활용할 수 있습니다.

const loginInput = document.querySelector("#login-form input");
const loginButton = document.querySelector("#login-form button");

function onLoginBtnClick(){
	const username = loginInput.value;
	if (username === ""){
		alert("Please write your name")
	} else if (username.length > 15){
		alert("Your name is too long")
	}
}

loginButton.addEventListener("click", onLoginBtnClick);

사실 input 태그에는 이미 글자수가 15개를 넘어가면 안된다는 기능이 있습니다. 이 기능은 input 태그를 form 태그로 감싸야 적용 가능합니다.

<form id="login-form">
	<input
		required
		maxlength = "15"
		type = "text"
		placeholder = "What is your name?"
	/>
</form>

html 을 위처럼 작성하면 됩니다. 대신 form 대그로 감싸면 입력 후 enter 를 누르거나 buttonclick 하면 submit 이란 이벤트가 발생합니다.

4.2 Events

submit 이란 event 를 감지해야 하므로 아래와 같이 코드를 수정합니다.

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

function onLoginSubmit(){
	console.log("hello", loginInput.value);
}

loginForm.addEventListener("submit", onLoginSubmit);

이렇게 하면 formsubmit 를 인지하고 바로 새로고침 됩니다. 우선 이 기본동작을 멈추어야 합니다

기본 적으로 함수는 () 괄호가 뒤에 붙어야 실행됩니다.

function
function() // 즉시 실행 

loginForm.addEventListener("submit", onLoginSubmit);
// 여기서 두번재 인자, 함수는 () 이 붙지 않아서 바로 실행되지 않음

onLoginSubmit(event);
// event 로부터 받은 정보가 () 안에 들어가서 실행 버튼을 누른다. 

기본 동작이 멈추게 하는 함수는 preventDefault() 입니다. 기존 코드를 수정해보면,

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

function onLoginSubmit(event){
	event.preventDefault(); // 기본동작 막기
	console.log(loginInput.value); 
}

loginForm.addEventListener("submit", onLoginSubmit);

4.3 Events part Two

form 의 기본동작은 submit 이었습니다. a 태그로 만든 링크의 기본동작을 확인해 봅니다.

const link = document.querySelector("a");
function handleLinkClick(){
	alert("clicked!");
}
link.addEventListener("click", handleLinkClick)
// 이렇게 하면 aler 이 링크의 기본동작을 막고 경고창을 먼저 띄웁니다.
// 경고창을 지우면 그제서야 동작합니다.

발생한 이벤트에 대한 정보는 함수의 인자로, 정보가 담긴 객체 형태로 전달됩니다.

handleLinkClick({info});

아래처럼 console.logevent 를 확인해보면,

const link = document.querySelector("a");
function handleLinkClick(event) {
	console.log(event);
	alert("clicked!");
}
link.addEventListener("click", handleLinkClick)

링크의 클릭은 submitEvent 가 아니라 mouseEvent 라는 것을 알 수 있습니다. screenX screenY 로 유저가 클릭한 위치 정보도 알 수 있습니다.

const link = document.querySelector("a");
function handleLinkClick(event){
	event.preventDefault(); // 이렇게 하면 링크의 기본동작 막는다.
	console.dir(event); // event 값 확인
}
link.addEventListener("click", handleLinkClick)

브라우저는 event 에 대한 정보를 담아주고, 우리는 자리를 만들어줍니다.

4.4 Getting Username

유저가 이름을 제출하면 form 을 없애고 싶다면, css 를 활용합니다.

.hidden {
	display: none;
}

유저가 이름을 제출한 후 formhidden 이란 클래스를 붙여줍니다. 전체 코드를 다시 써보면,

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

function onLoginSubmit(event){
	event.preventDefault(); // 이렇게 하면 링크의 기본동작 막는다.
	const username = loginInput.value;
	loginForm.classList.add("hidden") // 클래스 추가해서 안보이게
}

loginForm.addEventListener("submit", onLoginSubmit);

이제 htmlh1 태그를 추가합니다. hidden 클래스를 달아 처음엔 보이지 않게 하고, 텍스트가 입력될 경우 h1 태그에 넣어서 보여주게 하고 form 은 안 보이게 해줍니다.

// html 추가
<h1 id="greeting" class="hidden"></h1>

// js 추가 및 수정
const greeting = document.querySelector("#greeting")

function onLoginSubmit(event){
	event.preventDefault(); // 기본 동작 막고
	loginForm.classList.add("hidden") // 폼을 안 보이게
	const username = loginInput.value; // 사용자 입력값을 변수로 
	greeting.innerText = "Hello" + username; // h1 태그에 출력하고
	greeting.classList.remove("hidden"); // 눈에 보이게 히든을 없애주는
}

hidden 이란 class 이름이 반복되니까 변수로 지정합니다. 일반적으로 스트링만 포함된 변수는 대문자로 표기합니다.

const HIDDEN_CLASSNAME = "hidden";

위 변수를 넣어서 수정하고 표기방식을 약간 바꿔주면,

function onLoginSubmit(event){
	event.preventDefault(); // 기본 동작 막고
	loginForm.classList.add(HIDDEN_CLASSNAME) // 폼을 안 보이게
	const username = loginInput.value; / 사용자 입력값을 변수로 
	greeting.innerText = `Hello ${username}`; // h1 태그에 출력하고
	greeting.classList.remove(HIDDEN_CLASSNAME); // 눈에 보이게 히든을 없애주는
}

// "Hello" + username 는 이렇게 바꿀 수 있다. `Hello ${username}`

4.5 Saving Username

유저가 입력한 값을 기억하는 것은 흔한 기능이라 local storageAPI 가 존재합니다.개발자도구에서 Application 탭 좌측에서 볼 수 있습니다. 유저 정보를 저장하는 다양한 도구가 있는데 Session Stroage IndexedDB Web SQL Cookies Trust Tokens 개 중에 local storage 가 가장 다루기 쉽습니다.

local storage API 를 살펴보면 다양한 method 들이 있습니다.

localStorage.setItem('myCat', 'Tom')
// 아이템을 저장하는 기능

localStorage.getItem("myCat") // Tom
// 저장한 아이템 불러오기, 해당 key 값으로

localStorage.removeItem("myCat")
// 아이템 지우기

기존 코드에 추가해보면,

function onLoginSubmit(event){
	event.preventDefault(); 
	loginForm.classList.add(HIDDEN_CLASSNAME) 
	const username = loginInput.value; 
	localStorage.setItem("username", username)
	greeting.innerText = `Hello ${username}`; 
	greeting.classList.remove(HIDDEN_CLASSNAME); 
}

loginForm.addEventListener("submit", onLoginSubmit);

아직은 새로고침하고 저장된 username 이 뜨지 않는 상태입니다.

4.6 Loading Username

local storage 가 비어있으면 form 을 보여주고 local storage 에 정보가 으면 form 을 보여주지 않고 h1 만 보여줍니다.

먼저 할 일은 local storage 의 유저 정보 유무를 확인하는 것입니다.

localStorage.getItem("username")
// username 이 없으면 null 을 반환

변수를 만드고 조건문 기존 틀을 잡아보면,

const savedUsername = localStorage.getItem("username");

if (savedUsername === null) {
	// show the form
} else {
	// show the greeting
}

그리고 반복되는 username 은 오타가 날 수 있으면 변수로 고정합니다. string 오타는 js 가 지적하지 않지만 변수명 오타는 찾아서 알려줍니다.

const USERNAME_KEY = "username";

일단 form 도 처음에 보이지 않게 hidden 클래스를 달아주고 위 조건문을 작성해보면,

if (savedUsername === null) {
	loginForm.classList.remove(HIDDEN_CLASSNAME);
	loginForm.addEventListener("submit", onLoginSubmit);
} else {
	greeting.innerText = `Hello ${savedUsername}`;
	greeting.classList.remove(HIDDEN_CLASSNAME);
}

이전 코드들과 다 함께 써보면,

const loginForm = document.querySelector("#login-form");
const loginButton = document.querySelector("#login-form button");
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)
	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 {
	greeting.innerText = `Hello ${savedUsername}`;
	greeting.classList.remove(HIDDEN_CLASSNAME);
}

중복되는 코드는 아래처럼 함수로 묶어줄 수 있습니다.

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

이렇게 묶어서 다시 써보면,

const loginForm = document.querySelector("#login-form");
const loginButton = document.querySelector("#login-form button");
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(username); 
}

함수를 호출하는 위치에 따라 유저 정보는 다른 곳에서 옵니다. local storage 에 유저 정보가 있으면 거기서 정보를 받아서 인자로 넣어주고 없다면 입력되는 정보를 받아서 넣습니다.

profile
Today I Learned

0개의 댓글