[프로젝트] 바닐라 JS로 크롬 앱 만들기 4 로그인 구현

이하영·2023년 8월 7일
0

학습(프로젝트)

목록 보기
4/12
post-thumbnail

노마드 코더 - 바닐라 JS로 크롬 앱 만들기 강의

이제 본격적으로 app을 만들어보자.
유저의 정보를 받고 받은 정보를 화면에 표시하는 로그인 기능을 구현할 것이다.

강의 #4.0 Input Values

학습 날짜 : 23.08.07

우선 HTML을 작성한 다음 거기있는 요소들을 끌고 온다.
그런 다음에 JavaScript에서 이런저런 작업들을 해준다.

  • 사용자가 이름을 입력할 수 있도록 input 생성
<div id="login-form">
    <input type="text" placeholder="이름을 입력해주세요." />
    <button>로그인</button>
</div>
  • JavaScript로 input과 button을 끌고 온다.
const loginInput = document.querySelector("#login-form input");
const loginButton = document.querySelector("#login-form button");
  • 버튼을 클릭했을 때 input에 입력된 값을 확인한다.
    • value : input 안에 입력되어 있는 텍스트
function onLoginBtnClick(){
    console.log(loginInput.value);
    console.log("click!!")
}

loginButton.addEventListener("click", onLoginBtnClick);

강의 #4.1 Form Submission

학습 날짜 : 23.08.07

이번 강의에서는 username의 유효성 검사를 진행해보자.

  • JavaScript에서 유효성검사 진행
    • .length : 문자열 길이를 구할 수 있다.
function onLoginBtnClick(){
    const username = loginInput.value;
    if(username === ""){ //입력하지 않았을 경우
        alert("이름을 입력해주세요.");
    }else if(username.length > 15){ //username이 15글자를 초과한다면
        alert("이름이 너무 깁니다. 확인해주세요.");
    }
}
  • HTML Form input 태그에서 유효성검사 진행
    • input 태그를 꼭 form 태그 안에 위치시켜야 한다.
<form id="login-form">
    <input 
       required 
       maxlength="15" 
       type="text" 
       placeholder="이름을 입력해주세요." 
    />
    <button>로그인</button>
</form>
  • form 안에 있는 button을 누르거나 type이 submit인 input을 클릭하면 form이 submit 된다.
  • form 안에서 enter를 누르고 input이 더 존재하지 않는다면 자동으로 submit 된다.
  • submit를 했을 때 브라우저가 새로고침을 하지 않고 user 정보를 저장하여 사용하고 싶다.(다음 강의에서 알아보자.)

강의 #4.2 Events

학습 날짜 : 23.08.07

이번 강의에서는 브라우저가 새로고침을 하지 않고 user 정보를 저장할 수 있는 방법을 알아보자.

submit라는 event가 발생하는걸 막거나 중간에 개입해서 submit event가 발생했다는 것을 파악한다.

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);

브라우저는 enter를 누르거나 form을 submit하면 기본적으로 페이지를 새로고침 하도록 되어있다.

loginForm.addEventListener("submit", onLoginsubmit);

  • 이벤트가 발생했을 때만 onLoginsubmit을 호출한다.
  • EventListener function은 첫번째 argument로 정보를 전달한다.

preventDefault() 함수를 추가하여 브라우저의 기본 동작을 막을 수 있다.

function onLoginsubmit(event){
    event.preventDefault();
    console.log(loginInput.value);
}
  • preventDefault() : 어떤 event의 기본 행동들을 발생하지 않도록 막는다.

강의 #4.3 Events part Two

학습 날짜 : 23.08.07

  • submit의 기본 동작 → 새로고침
  • 링크의 기본 동작 → 클릭 시 다른 페이지로 이동
  • 브라우저는 링크를 클릭할 때 해당 사이트로 이동하게 설정되어 있는데
    event.preventDefault();를 통해 기본 동작을 막을 수 있다.
const link = document.querySelector("a");

function handleLinkClick(event){
    event.preventDefault();
    console.dir(event);
    alert("clicked!");
}

link.addEventListener("click", handleLinkClick);
  • addEventListener 안에 있는 함수는 직접 실행하는 것이 아니고 브라우저가 실행시켜준다. 그때 브라우저에서 해당 이벤트에 대한 정보 object를 가지게 된다.
    우리는 함수에서 object에 대한 자리만 할당해주면 해당 이벤트가 발생시킨 정보들을 확인할 수 있다. (함수 첫번째 argument에 공간을 할당, 보통은 event라고 작성하는 것이 관행이다.)
    ex) function handleLinkClick(event){}

강의 #4.4 Getting Username

학습 날짜 : 23.08.07

이제 사용자가 이름을 제출하면 form을 없애보자.

  • HTML 요소 자체를 없애는 방법
  • CSS를 이용해서 숨기는 방법
    • hidden이라는 class name을 추가
.hidden{
    display: none;
}
function onLoginSubmit(event){
    event.preventDefault();
    const username = loginInput.value;
    loginForm.classList.add("hidden");
    console.log(username);
}

사용자가 이름을 입력하고 제출했을 때, form은 없애고 문구가 나올 수 있도록 구현해보자.

<form id="login-form">
        <input 
            required 
            maxlength="15" 
            type="text" 
            placeholder="이름을 입력해주세요." 
        />
        <button>로그인</button>
    </form>
    <h1 id="greeting" class="hidden"></h1>
const loginForm = document.querySelector("#login-form");
const loginInput = document.querySelector("#login-form input");
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 = "안녕하세요. " + username + "님";
    greeting.classList.remove(HIDDEN_CLASSNAME);
}

loginForm.addEventListener("submit", onLoginSubmit);
  • const HIDDEN_CLASSNAME = "hidden";
    string만 포함된 변수는 대문자로 쓰는 관습이 있다.(+중요한 변수가 아닐 때)
  • loginForm은 hidden이라는 class name을 추가해주고, greeting은 기존에 있던 hidden이라는 class name을 삭제해준다.
greeting.innerText = "안녕하세요. " + username + "님"; 
greeting.innerText = `안녕하세요. ${username}`;

두 코드는 같다. 둘 다 문자열과 변수를 하나로 합쳐준다.

<변수와 string을 결합하는 규칙>

1. `(백틱) 기호로 시작하고 끝나야한다.
2. 변수명은 ${변수명} 으로 표현한다.

강의 #4.5 Saving Username

학습 날짜 : 23.08.08

value를 저장하는 방법

  • local storage(API) 활용
    • 브라우저에 뭔가를 저장할 수 있게 해준다.
    • 저장한 것을 나중에 가져다 쓸 수 있다.
    • local storage 확인 방법
      개발자 도구 - application - Local Storage
    • .setItem(key값,value값) : local storage에 정보를 저장한다.
    • .getItem(key값) : local storage에 있는 정보를 가져온다.
    • .removeItem(key값) : local storage에 있는 정보를 삭제한다.
function onLoginSubmit(event){
    event.preventDefault();
    loginForm.classList.add(HIDDEN_CLASSNAME);
    const username = loginInput.value;
    localStorage.setItem("username", username);
    greeting.innerText = `안녕하세요. ${username}`;
    greeting.classList.remove(HIDDEN_CLASSNAME);
}


강의 #4.6 Loading Username

학습 날짜 : 23.08.08

local storage에 유저 정보가 없으면 form을 보여주어 사용자가 정보를 입력하게 하고, local storage에 유저 정보가 있으면 form이 안보이고 인사 문구(h1)가 보이도록 구현해보자.

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

const link = document.querySelector("a");
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){
    //form 보여줌
    loginForm.classList.remove(HIDDEN_CLASSNAME);
    loginForm.addEventListener("submit", onLoginSubmit); //이벤트가 발생했을 때만 onLoginsubmit을 호출한다.
}else{
    //greeting 보여줌(form 사라짐)
    paintGreetings(savedUsername);
}
  • 중복되는 코드가 있을 경우, 함수로 분리하여 코드를 줄일 수 있다.
    greeting.innerText = `안녕하세요. ${username}`;
    greeting.classList.remove(HIDDEN_CLASSNAME);

위 코드가 함수 onLoginSubmit와 if else문에 중복으로 들어가게 된다.

function paintGreetings(username){
    greeting.innerText = `안녕하세요. ${username}`;
    greeting.classList.remove(HIDDEN_CLASSNAME);
}

paintGreetings라는 함수로 분리하여 각각 매개변수를 받아 사용하면 코드를 줄일 수 있다.

paintGreetings(username);

  • loginInput.value에서 받은 값을 매개변수로 받아 사용

paintGreetings(savedUsername);

  • localStorage에 저장된 값을 매개변수로 받아 사용

강의 #4.7 Super Recap

학습 날짜 : 23.08.08

지금까지 구현한 내용 복습
local storage에 정보가 없다면 form을 보여주어 사용자가 정보를 입력할 수 있도록 하고, 정보가 이미 있다면 form을 보여주지 않고 인사 문구를 보여주도록 구현한다.

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

const link = document.querySelector("a");
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){
    //form 보여줌
    loginForm.classList.remove(HIDDEN_CLASSNAME);
    loginForm.addEventListener("submit", onLoginSubmit); 
}else{
    //greeting 보여줌(form 사라짐)
    paintGreetings(savedUsername);
}
  • username(정보)이 없다면 if(savedUsername === null)

  • loginForm의 HIDDENCLASSNAME을 제거한다.
    loginForm.classList.remove(HIDDEN_CLASSNAME);

  • loginForm에 EventListener를 더하고 submit를 기다린다.
    loginForm.addEventListener("submit", onLoginSubmit);

  • submit 이벤트가 발생하면 onLoginSubmit 함수가 실행된다.

  • 화면 새로고침 방지하기event.preventDefault();

  • form을 다시 숨긴다.
    loginForm.classList.add(HIDDEN_CLASSNAME);

  • loginInput.value를 username이라는 변수로 저장한다.
    const username = loginInput.value;

  • local storage에 사용자가 입력한 정보(loginInput.value)를 username이라는 key값에 저장한다.
    localStorage.setItem(USERNAME_KEY, username);

    • 인사 문구를 출력하는 함수 paintGreetings를 호출한다.
      paintGreetings(username);
      → 사용자가 입력한 username을 매개변수로 받아 사용
  • 함수 paintGreetings

    • username이라는 인자를 하나 받고있다.
    • 비어있는 h1 요소에 인사 문구를 추가한다.
    • h1 요소의 "hidden"이라는 클래스명을 제거한다.(인사 문구를 보여준다.)
  • username(정보)이 있다면 else

    • 인사 문구를 출력하는 함수 paintGreetings를 호출한다.
      paintGreetings(savedUsername);
      → localStorage에 저장된 값을 매개변수로 받아 사용
const loginForm = document.querySelector("#login-form");
const loginInput = document.querySelector("#login-form input");
const greeting = document.querySelector("#greeting");

const link = document.querySelector("a");
const HIDDEN_CLASSNAME = "hidden";
const USERNAME_KEY = "username";

function onLoginSubmit(event){
    event.preventDefault();
    loginForm.classList.add(HIDDEN_CLASSNAME);
    localStorage.setItem(USERNAME_KEY, username);
    paintGreetings();
}

function paintGreetings(){
    const username = localStorage.getItem(USERNAME_KEY);
    greeting.innerText = `안녕하세요. ${username}`;
    greeting.classList.remove(HIDDEN_CLASSNAME);
}

const savedUsername = localStorage.getItem(USERNAME_KEY);

if(savedUsername === null){
    //form 보여줌
    loginForm.classList.remove(HIDDEN_CLASSNAME);
    loginForm.addEventListener("submit", onLoginSubmit); 
}else{
    //greeting 보여줌(form 사라짐)
    paintGreetings();
}
  • local storage에 username을 저장하고 paintGreetings 함수를 호출한다.
    → paintGreetings 함수를 호출하는 순간에 username은 이미 local storage에 저장되어 있다.
    → paintGreeting 함수에서 매개변수를 받을 필요없고, onLoginSubmit 함수에서 username 변수를 만들 필요 없다.
    이 방법을 사용하면 local storage를 두 번 열어보게 된다. 처음 구현했던 방법을 사용하거나 이 방법을 사용하거나 똑같이 작동한다.
    어떤 방법으로 할지는 마음대로 선택하면 되지만, 굳이 local storage를 두 번 열어볼 필요는 없으니 처음 구현했던 방법으로 진행하려고 한다.
profile
안녕하세요, 웹 개발자 이하영입니다!

0개의 댓글