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

딩쓰·2022년 11월 27일
post-thumbnail

이 글은 노마드코더 바닐라JS로 크롬앱 만들기를 수강하면서 내용을 정리한 글입니다.

#4 LOGIN 4.0~4.7

Login

이번 강의에서 할 일은
1. user에게 질문을 해야 함 => 당신은 누군가요? 이름이 뭔가요?
2. 위의 정보들을 어떻게 받을지에 대해
3. 받은 정보를 화면에 표시하기.

Input Values

HTML을 작성한 다음 HTML의 요소를 가져와서 JS에서 작업을 해야함.
id가 login-form인 div 요소를 이용해서 input과 button을 가져올 수 있다.

//index.html
<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>

아래의 두가지 방법 모두 가능한데 querySelector()를 사용할 때는 대상이 id인지 명확히 해줘야 함.
=> querySelector()로는 classname,tagname 모두 검색 가능하기 때문에

const loginForm = document.getElementById('login-form');
const loginInput = loginForm.querySelector('input');
const loginButton = loginForm.querySelector('button');

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

이제 사용자의 정보를 console.log로 가져오기 위해 click event를 만들어 loginButton에 연결한다.
우린 loginButton에 대한 click을 감지할 준비가 됐음.

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

function onLoginButtonClick() {
  console.dir(loginInput)
  console.log("click!!!");
}

loginButton.addEventListener('click', onLoginButtonClick);

우선 console.dir(loginInput)을 해줘서 loginInput의 내부를 보면 아래처럼 일반적인 object임.

이중 value를 찾으면 input창에 입력한 값을 찾을 수 있음.

아래와 같이 미리 value를 입력할 수도 있음.

 <input
       value = "lalala"
       type="text"
       placeholder="What is your name?"    
    />

버튼을 클릭했을 때 입력된 값이 무엇인지 가져올 수 있고, input.value는 해당 input에 입력된 값이다.

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

function onLoginButtonClick() {
  console.log('hello', loginInput.value);
}

loginButton.addEventListener('click', onLoginButtonClick);

Form Submission

이번 강의에서는 username의 유효성을 검사할 것임.
우선 username이 비어있으면 안되고, 너무 긴 username이어도 안됨.
매번 loginInput.value를 적는 것 대신에 우리는 이걸 변수에 할당할 것임.

사용자가 입력값을 입력하지 않거나 길이가 15자가 넘으면 아래와 같이 코드를 작성한다.
문자열.length로 문자열의 길이를 구할 수 있음.

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

위에 처럼 코드를 작성하는건 JS만으로만 작업시에는 필요하지만 브라우저 자체의 기능을 사용하는 방법도 있음!
(항상 최고의 툴을 사용해야 하고, 이미 가지고 있는 기능들을 사용하는게 좋음)
브라우저 자체의 기능을 이용해서 input의 유효성 검사를 작동시키기 위해서는 아래처럼 form 안에 input이 있어야 함.
form을 이용하면 input을 필수 입력 항목으로 만들 수 있고 (required), 자체적으로 최대 글자수를 조절할 수 있음. (maxlength)

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

Events

이제는 button이 아닌 submit event를 감지할건데 , form 안에 있는 버튼을 누르거나 type이 submit인 input에서 엔터를 누르면 자동으로 새로고침이 일어남. 새로고침이 일어나는건 form submit의 브라우저 기본 동작인데 우리는 새로고침 하지 않고 사용자의 정보를 저장해야 함.
=> submit 이벤트가 발생하는걸 막거나 중간에 개입해서 이벤트가 발생했다는 걸 파악해야 함.

중요한 건, 아래의addEventListener에서 submit event가 발생할 때 JS는 onLoginSubmit을 호출하는데 onLoginSubmit() 이런식의 비어있는 모습이 아닌, onLoginSubmit({information}) 이런식으로argument안에 첫번째 인자로 발생한 event의 대해 여러 정보들을 event object로 담아서 우리들에게 제공함.

event.preventDefault() : 이벤트의 기본 동작(함수에 대해 브라우저가 기본적으로 하는 동작)이 발생하지 않도록 막는다. 여기선 submit의 기본동작(새로고침 되는것)을 막음.

function onLoginSubmit(event) {
  event.preventDefault();
  console.log(loginInput.value);
}

loginForm.addEventListener('submit', onLoginSubmit);

-방금 실행된 event에 대한 여러 정보들임.(console.log(event);로 확인)

submitter : input : submit 주체는 input이다.
target : form : 대상은 form 이다 .

function handleLinkClick(event){
  event.preventDefault();
  console.dir(event)
}

link.addEventListener("click", handleLinkClick);

위의 코드에서 링크(link)의 경우 기본 동작이 클릭 시 다른 페이지로 이동하는 것이다. 하지만 event.preventDefault()로 링크의 페이지에 가는걸 막았고, 이벤트 리스너의 함수에서 PointerEvent 이벤트 객체를 콘솔에 출력하면 다음과 같이 나온다.

  • screenXscreenY: 클릭한 위치의 X, Y 좌표를 보여준다.
  • path : [a, body, html, document, Window]로 나오는데 어디에서 클릭이 발생했는지 array로 알려줌
  • defaultPrevented: true이면 브라우저가 하려는 동작을 허용하지 않고 막아버림.

💡 중요한건 addEventListener안에 있는 함수는 우리가 직접 실행하는게 아니라 브라우저가 이벤트를 감지하고 실행하며 event에 대한 정보를 함께 인자로 넘겨주는 것이다!

Getting Username 

css를 이용해서 유저가 이름을 제출하면 form을 없애보자. 이때 사용자의 이름은 변수에 저장해둔다.

//css파일에서 작성.
.hidden{
  display: none;
}
function onLoginSubmit(event) {
  event.preventDefault();
  loginForm.classList.add('hidden'); //classList.add : 클래스를 추가하는 것
  const username = loginInput.value;
}

loginForm.addEventListener("submit",onLoginSubmit)

저장해둔 사용자의 이름을 h1 태그로 표시한다.

//index.html
<h1 id="greeting" class="hidden"></h1>
//app.js
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 = `Hello ${username}`;
  greeting.classList.remove(HIDDEN_CLASSNAME);
}

일반적으로 string만 있는 값을 변수에 저장할 때 변수명을 대문자로 표기한다. 대문자 변수로 저장해놓으면 실수 없이 문자열을 사용할 수 있다.

문자열을 합칠 때 +로 합칠 수도 있지만, Hello ${username} 처럼 템플릿 리터럴 방법을 추천함.

Saving Username

이제 할 건, 사용자가 제출한 값을 브라우저에 저장하는 것임. 뭔가를 저장하는 건 자주 사용되는 기능이다.
ex) 유튜브에서 볼륨을 조절하고 새로고침 하면 유튜브는 이전의 볼륨값을 기억해야함.
local storage를 사용하면 브라우저에 뭔가를 저장해서 나중에 가져다 쓸 수 있음. 개발자 도구의 Application에서 로컬 스토리지에 뭐가 들어있는지 확인할 수 있다. 마치 작은 DB처럼 우리는 key와 value만 있으면 됨. local storage mdn

  • localStorage.setItem(): 로컬 스토리지에 정보 저장
  • localStorage.getItem(): 로컬 스토리지에 저장되어 있는 값 불러오기
  • localStorage.removeItem(): 로컬 스토리지에 저장되어 있는 값 삭제

Loading Username

h1과 form을 둘 다 보여주지 않다가 로컬 스토리지에 유저 정보가 있는지 확인하고, 있으면 h1 요소를 보여주고 없으면(null) form을 보여준다.

'username' 문자열이 반복되어 사용되므로 USERNAME_KEY로 변수화한다.

greeting.innerTextgreeting.classList.remove 반복을 없애기 위해 함수(paintGreetings)로 만든다.

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

완성된 화면

profile
Frontend Developer

0개의 댓글