ABOUT ME

-

Today
-
Yesterday
-
Total
-
  • 바닐라JS 로 만드는 북마크 웹앱 📓 (1) 회원가입, 로그인 편
    으쌰으쌰 2023. 1. 25. 16:16

     

    대망의 1편!

     

    바닐라 JS로 만드는 북마크 웹앱 📓 1편

    ~ 회원가입, 로그인 편 ~

     

    로컬스토리지를 사용해서 회원가입, 로그인 기능을 구현하는 건 저번에 해 본 경험이 있다.

    덕분에 (처음보다) 쉽게 구현할 수 있었다.

    최선을 다했지만 그때보다 더 적당한 코드를 사용했는지, 무엇을 수정하면 좋았을지.. 등등  혼자 판단하기 어려웠다는 점이 아쉽다. 

    하지만 이것만은 확실하게 깨닫고 있다. 기록은 언제 어디서든 도움이 될 수 있다는 사실!

    간단하게 회원가입, 로그인 기능을 구현한 코드 등을 남겨둔다. 🤸🏻

     

     


     

     

    천 리 길도 한 걸음부터, 로그인 회원가입 기능 구현 게시물 보러 가기 👏

    (1) 회원가입 편

    (2) 로그인 편

    (3) 총정리 편

     

     

     


     

     

    ✔︎ 회원가입

    1. ID 중복 검사 (입력받을 때마다 체크)

    2. 비밀번호 확인 검사 (같은 비밀번호를 썼는지)

    3. 비밀번호를 수정할 경우, 비밀번호 확인 창은 초기화 (다시 한번 변경된 비밀번호를 확인받아야 함)

    4. 저번에는 input type date로 받았던 생일 정보를 select 로 바꾸기

    5. 회원정보를 localStorage에 저장 (아이디 중복확인, 비밀번호 확인까지 완료된 상태여야 정보가 저장됨)

    6. localStorage 저장 후 확인 팝업 > index.html로 이동

     

     

    0. 전역 변수, 이벤트 리스너

    // 전역변수
    const userForm = document.querySelector("#userForm");
    const userId = document.querySelector("#userId");
    
    const userPw = document.querySelector("#userPw");
    const userPwCheck = document.querySelector("#userPwCheck");
    const checkPwSpan = document.querySelector("#checkPw");
    
    const month = document.querySelector("#userBirthMonth");
    const day = document.querySelector("#userBirthDay");
    
    const user = JSON.parse(localStorage.getItem("user"));
    const PASSID_KEY = "사용하실 수 있습니다.";
    const PASSPW_KEY = "비밀번호 확인 완료!";
    
    // 이벤트리스너
    userForm.addEventListener("submit", saveUserInfo); // 작성한 정보를 로컬스토리지에 저장
    userId.addEventListener("keyup", checkId); // 아이디 중복 검사
    userPwCheck.addEventListener("keyup", checkPw); // 비밀번호 확인 검사
    userPw.addEventListener("keydown", resetPw); // 비밀번호 변경시 비밀번호 확인 인풋창 초기화

     

     

    1. ID 중복 체크

    사용자가 한 글자 입력할 때마다 input 옆 span 으로 나타나게 설정했다.

    개인적이고 주관적인 경험으로 만들어져서 그런지 내가 사용하면서 편했던 방법대로 최대한 만들려고 노력했다. (모든 기능을)

    특히 인풋창 가까이에 결과를 나타내주는 게 나중에 form을 submit 한 이후에야 알 수 있는 것보다 편하다고 느꼈기에 이 방법을 선택했다. 

    // id 중복체크
    function checkId() {
      const checkIdSpan = document.querySelector("#checkId");
      const reg = /[^\w]+/g;
    
      if (user.id === userId.value) {
        checkIdSpan.innerText = "중복된 아이디입니다.";
      } else if (userId.value.match(reg)) {
        checkIdSpan.innerText = "영어 / 숫자 / _만 사용 가능합니다";
      } else if (userId.value.length < 4) {
        checkIdSpan.innerText = "4자 이상이어야 합니다.";
      } else {
        checkIdSpan.innerText = PASSID_KEY;
        return PASSID_KEY;
      }
    }

    👏 저번에는 정규 표현식을 사용할 때 [a-zA-Z] ... 식으로 만들고 충분한 이해 없이 사용했다는 느낌이었다면, 이번에는 정규식을 공부한 이후라(공부한 포스팅은 여기!) \w와 + 등 쓰는 이유를 확실히 알고 사용했다는 점이 저번과 사뭇 달랐다. 좋아좋아. 정규식이 완전히 익숙해질 때까지 달려~ 🧑‍💻

     

     

    2. 비밀번호 확인 검사

    // 비밀번호 확인 검사
    function checkPw() {
      if (userPwCheck.value !== userPw.value) {
        checkPwSpan.innerText = "비밀번호가 같지 않습니다.";
      } else {
        checkPwSpan.innerText = PASSPW_KEY;
        return PASSPW_KEY;
      }
    }

     

    ❓저번에는 return 값을 만들지 않았었다. (아이디, 비번 둘 다) 나중에 PASSPW_KEY가 담겨있는지 확인할 때 if문 조건 부분이 너무 길어지는 걸 방지하고 싶어서 return 값에 PASSPW_KEY를 담았는데 결국 둘 다 원하는 기능이 구현되긴 하지만 어떤 방법이 더 나은 방법인지는 잘 모르겠다. 사실 큰 차이 없는 거 같기도 하고 ... 🧐

     

     

    3. 비밀번호 변경 시 비밀번호 확인 input 초기화

    // 비밀번호 수정 시 비밀번호 확인 input 초기화
    function resetPw() {
      userPwCheck.value = "";
      checkPwSpan.innerText = "";
    }

    🍔 특별한 변경사항 없음.

     

     

    4. 생일 정보 select 사용해서 받기

    <div class="">
      <span>생일</span>
      <select name="" id="userBirthMonth"><!--option js 추가--></select><label for="userBirthMonth">월</label>
      <select name="" id="userBirthDay"><!--option js 추가--></select><label for="userBirthDay">일</label>
    </div>
    //onload date select option value 
    window.onload = function () {
      for (let i = 1; i <= 12; i++) {
        let m = document.createElement("option");
    
        if (i < 10) {
          m.innerText = "0" + i;
          m.value = "0" + i;
        } else {
          m.innerText = i;
          m.value = i;
        }
        month.appendChild(m);
      }
    
      let lastDay = 31;
      for (let j = 1; j <= lastDay; j++) {
        let d = document.createElement("option");
        if (j < 10) {
          d.innerText = "0" + j;
          d.value = "0" + j;
        } else {
          d.innerText = j;
          d.value = j;
        }
        day.appendChild(d);
      }
    };

    👏 저번에는 input type = "date" 로 받았던 생일 정보가 직접 할 때 불편하다고 느꼈기 때문에 select로 바꿔보기로 했다. 

    select 를 사용하기 위해서는 select 태그 안에 여러 개의 option 태그를 사용해야 하는데 html에 다 담기는 너무 더러워 보여서(5개 정도면 모르겠는데 월은 12개고 일은 31개나 된다...) + js 익숙해지기 위해서 option과 value 등등을 js로 만들기로 했다. 

    ❓ 처음에는 html 파일에 script로 바로 실행될 수 있도록 작성했다. 그런데 모든 관련 기능은 js 파일로 옮기는 게 좋은가 싶어서 js 파일로 옮겼다. 나는 function은 모두 js 파일에 정리해두고 싶은 파라 더 낫다고 느꼈지만, 실제로 성능면(?)에서 어느 쪽이 더 나은지는 잘 모르겠다. 관련해서는 찾아봐야겠다. 

     

    ❓31일까지 있는 달을 선택하면 31일까지 선택지가 나오고, 30일까지 있는 달을 선택하면 30일까지 나오고 ... 그런 식으로 구현하고 싶었는데 계속 막히고 있다. if문을 추가해서 month value를 받아서 lastDay 값을 변경하면 될 거라고 생각했는데 전혀 ... 이미 페이지와 함께 로드된 이후라서 그런 걸까? 그러면 month를 변경할 때마다 -> 값을 받아오고 -> 그 값에 맞춰서 lastDay 변경 -> 결과 day 옵션 수 변경 이런 식으로 해야 할 것 같은데 그럼 eventListner를 사용해야 하지 않나 ... 🧐 계속 도전해 보고 완성되면 이후 포스팅에 기록하겠다.

     

     

    5. 작성한 정보를 localStorage에 저장

    이때 아이디 중복확인, 비밀번호 확인이 정상적으로 끝나있어야 한다.

    // 회원정보 local storage에 저장
    function saveUserInfo(e) {
      e.preventDefault();
    
      if (checkId() === PASSID_KEY && checkPw() === PASSPW_KEY) {
        const userName = document.querySelector("#userName");
    
        const userObj = {
          id: userId.value,
          pw: userPw.value,
          name: userName.value,
          birth: month.value + day.value,
        };
    
        localStorage.setItem("user", JSON.stringify(userObj));
        alert("회원가입이 완료되었습니다!");
        location.assign("index.html");
      } else {
        alert("아이디 혹은 비밀번호를 확인하세요.");
      }
    }

    👏 나머지는 저번 구현과 거의 비슷해서 큰 변화가 없다. 하지만 단 하나! 위에서 생성했던 return값들. 여기서 써먹는다! 처음에는 return 값을 받는 변수를 만들었었는데, 큰 필요가 없는 것 같아서 그대로 함수를 쓰는 걸로 바꿨다. 

     

     

     


     

     

     

    ✔︎ 로그인

    1. 로그인 폼 submit 시 function 동작

    2. 로그인 성공했을 시, 로그인 폼 사라지고 회원 닉네임 환영인사

    3-1. 로그인 실패했을 시, 아이디가 존재하지 않는 경우 > 존재 x 팝업

    3-2. 비밀번호가 틀린 경우 > 비밀번호 재확인 요청 팝업

     

     

    0. 전역변수, 이벤트리스너

    // 전역변수
    const loginForm = document.querySelector("#loginForm");
    
    // 이벤트리스너
    loginForm.addEventListener("submit", login);

    회원가입보다는 훨씬 간단한 로그인 기능!

     

     

    function login(e) {
      e.preventDefault();
    
      const id = document.querySelector("#idInput");
      const pw = document.querySelector("#pwInput");
      const users = JSON.parse(localStorage.getItem("user"));
    
      if (users.id === id.value && users.pw === pw.value) {
        const span = document.querySelector("#greetingSpan");
        const loginBox = document.querySelector("#loginBox");
    
        loginBox.classList.add("hidden");
        span.innerText = `${users.name}님 반가워요!`;
      } else {
        const answer =
          users.id !== id.value ? "아이디가 없습니다" : "비밀번호를 확인하세요";
        alert(answer);
      }
    }

    👏  저번보다 깔끔하게! 가 작은 목표들 중 하나이기 때문에 ㅎㅎ ... 이번에는 삼항 연산자를 사용해봤다 ! 너무 길어지지 않고 이정도로 간단한 정도라면 삼항연산자가 그렇게 가독성을 해치지는 않는 느낌 🧐 라고 생각했다. 

     

     

     

     


     

     

     

     

    나름대로 노력했는데 노력한만큼 나아졌는지는 사실 잘 모르겠다!

    그저 꾸준히 이게 다 낫겠다 싶은 것들을 추가 수정하는 수행 중 ... 🤸🏻 공부 또 공부 신나신나~ 

    다음은 이번 웹앱 프로젝트의 꽃🌸 게시물 추가 수정 삭제 확인 기능 구현으로 돌아오겠다 ! 아듀~

     

     

     

     

     

     

     

    댓글

Designed by Tistory.