ABOUT ME

-

Today
-
Yesterday
-
Total
-
  • localStorage 를 이용해서 로그인 / 회원가입 구현하기! (3) 수정, 추가 마지막 정리 편
    으쌰으쌰 2023. 1. 21. 18:42

     

    GIT🧑‍💻

     

    회원가입 완성!
    로그인 완성!

     

    gif 촬영이 조금 이상하게 됐지만 ... 원하던 기능을 구현하는 데에 성공! 했다.

    js 코드 수정을 꽤 했는데 그래도 나름 이해했다고(?) 원하는대로 변경돼서 다행이었다.

    완성한 걸 보니 허접하지만서도 뿌듯함을 감출 수가 없군 ~~ 다음에 만들 것도 열심히 만들어봐야겠다!!

     


     

    완성한 코드 👇

    <!DOCTYPE html>
    <html lang="en">
    <head>
      <meta charset="UTF-8">
      <meta http-equiv="X-UA-Compatible" content="IE=edge">
      <meta name="viewport" content="width=device-width, initial-scale=1.0">
      <title>로그인</title>
      <link rel="stylesheet" href="css/style.css" />
    </head>
    <body>
      
      <div class="main">
    
        <div class="allBox">
    
          <!--greeting-->
          <div class="box">
            <h1>로그인</h1>
          </div>
      
          <!--login form-->
          <div class="box">
            <form action="" id="loginForm">
          
              <div class="box">
                <input type="text" placeholder="아이디" id="idInput" autocomplete="off" />
              </div>
              <div class="box">
                <input type="password" placeholder="비밀번호" id="pwInput" autocomplete="off" />
              </div>
          
              <div class="btnBox">
                <button id="loginBtn">로그인</button>
              </div>
        
              <div class="box">
                <span>
                  <a href="signup.html">회원가입</a>
                </span>
              </div>
            </form>
          </div>
    
        </div>
    
      </div>
    
      <!--js load-->
      <script type="text/javascript" src="js/login.js"></script>
    </body>
    </html>

    index.html (login)

     

    <!DOCTYPE html>
    <html lang="en">
    <head>
      <meta charset="UTF-8">
      <meta http-equiv="X-UA-Compatible" content="IE=edge">
      <meta name="viewport" content="width=device-width, initial-scale=1.0">
      <link rel="stylesheet" href="css/style.css" />
      <title>회원가입</title>
    </head>
    <body>
    
      <div class="main">
        <div class="allBox">
    
          <h1>회원가입</h1>
      
          <form action="" id="signUpForm">
            <div class="sufInput">
              <label for="idInput">아이디</label>
              <input type="text" id="idInput" placeholder="4자이상 10자이하" maxlength="10" minlength="4" autocomplete="off" required />
              <span id="idCheckSpan"></span>
            </div>
            <div class="sufInput">
              <label for="pwInput">비밀번호</label>
              <input type="password" id="pwInput" placeholder="6자이상 10자이하" maxlength="10" minlength="6" autocomplete="off" required />
              <span id="pwLengthSpan"></span>
            </div>
            <div class="sufInput">
              <label for="pwCheckInput">비밀번호 확인</label>
              <input type="password" id="pwCheckInput" placeholder="비밀번호를 똑같이 입력하세요!" maxlength="10" minlength="6" autocomplete="off" required />
              <span id="pwCheckSpan"></span>
            </div>
            <div class="sufInput plusMargin">
              <label for="nameInput">닉네임</label>
              <input type="text" id="nameInput" placeholder="8자이하" maxlength="8" autocomplete="off" required />
            </div>
            <div class="sufInput plusMargin">
              <label for="birthinput">생일(선택)</label>
              <input type="date" id="birthInput" min="1920-01-01" />
            </div>
        
            <div class="btnBox">
              <button id="signUpBtn">가입</button>
            </div>
          </form>
    
        </div>
      </div>
    
      <!--js load-->
      <script type="text/javascript" src="js/signup.js"></script>
      <script>
        const birth = document.querySelector("#birthInput");
        const today = new Date();
    
        const maxDay = `${today.getFullYear()}-${""+today.getMonth()+1}-${today.getDate()}`;
        birth.setAttribute("max", maxDay);
        console.log(maxDay);
        
      </script>
    </body>
    </html>

    signup.html

     

    .hidden {
      display: none;
    }
    
    html, body {
      height: 100%;
      margin: 0;
    }
    
    .main {
      height: 100%;
      display: flex;
      flex-direction: column;
      align-items: center;
      justify-content: center;
      text-align: center;
      background: rgb(251,230,151);
      background: radial-gradient(circle, rgb(255, 241, 191) 0%, rgb(156, 209, 105) 100%);
    }
    
    .main input {
      padding: 8px;
      margin: 5px 0;
      
      width: 200px;
      height: 20px;
    }
    
    .main input:focus {
      outline: 2px solid rgb(156, 209, 105);
    }
    
    .main h1 {
      margin: 20px 0;
    }
    
    .main a {
      color: rgb(106, 106, 106);
      font-size: 10pt;
      text-decoration: none;
    }
    
    .main a:hover {
      text-decoration: underline;
    }
    
    .allBox {
      background-color: rgba(255, 251, 210, 0.8);
      border: 1px solid rgb(255, 251, 210);
      border-radius: 20px;
      box-shadow: 0px 0px 8px rgb(255, 251, 210);
      padding: 100px 80px;
    }
    
    .btnBox {
      margin: 25px 0 15px 0;
    }
    
    .btnBox button {
      padding: 10px 40px;
      background-color: rgba(156, 209, 105, .5);
      border: none;
      border-radius: 5px;
      margin: 10px 0;
    }
    
    .btnBox button:hover {
      background-color: rgba(156, 209, 105, 1);
    }
    
    label {
      display: block;
      padding: 5px 0;
      margin-top: 5px;
      text-align: left;
      font-size: 11pt;
    }
    
    .sufInput span {
      display: block;
      font-size: 10pt;
      color: rgb(175, 37, 37);
      padding: 10px;
    }
    
    .plusMargin {
      margin-bottom: 20px;
    }

    style.css

     

    const loginForm = document.querySelector("#loginForm");
    
    function login(event) {
      const idInput = document.querySelector("#idInput");
      const pwInput = document.querySelector("#pwInput");
    
      event.preventDefault();
    
      const idValue = JSON.parse(localStorage.getItem("user"));
      if (idValue != null && idValue.id === idInput.value) {
        console.log(idValue.id);
        if (idValue.pw === pwInput.value) {
          // 로그인 성공하면 html 변신~
          const mainString = document.querySelector("h1");
          loginForm.classList.add("hidden");
          mainString.innerText = `${idValue.name}님 환영합니다!`;
        } else {
          alert("비밀번호를 확인하세요");
          pwInput.value = "";
        }
      } else if (idValue.id !== idInput.value) {
        alert("없는 아이디입니다.");
        idInput.value = "";
        pwInput.value = "";
      }
    }
    
    loginForm.addEventListener("submit", login);

    login.js

     

    const signUpForm = document.querySelector("#signUpForm");
    const idInput = document.querySelector("#idInput");
    const idCheckSpan = document.querySelector("#idCheckSpan");
    
    const pwInput = document.querySelector("#pwInput");
    const pwCheckInput = document.querySelector("#pwCheckInput");
    const pwCheckSpan = document.querySelector("#pwCheckSpan");
    
    const IDOK_KEY = "아이디를 사용하실 수 있습니다.";
    const PWOK_KEY = "비밀번호가 확인되었습니다!";
    
    // 아이디 중복체크
    function idCheck() {
      const ID_KEY = idInput.value;
      const getId = localStorage.getItem("user");
      const obj = JSON.parse(getId);
      const engReg = /^[a-zA-Z0-9]/;
      const etcReg = /[^a-zA-Z0-9]/gi;
    
      if (
        3 < ID_KEY.length &&
        obj.id !== ID_KEY &&
        engReg.test(ID_KEY) &&
        !etcReg.test(ID_KEY)
      ) {
        idCheckSpan.innerText = IDOK_KEY;
      } else if (!engReg.test(ID_KEY) || etcReg.test(ID_KEY)) {
        idCheckSpan.innerText = "영어와 숫자만 사용할 수 있어요.";
      } else if (ID_KEY.length < 4) {
        idCheckSpan.innerText = "아이디는 4글자 이상으로 정해주세요.";
      } else if (obj.id === ID_KEY) {
        idCheckSpan.innerText = "이미 있는 아이디예요";
      }
    }
    
    // 비밀번호 중복체크
    function pwCheck() {
      if (pwInput.value === pwCheckInput.value) {
        pwCheckSpan.innerText = PWOK_KEY;
      } else pwCheckSpan.innerText = "비밀번호를 확인하세요";
      // 비밀번호 수정하면 비밀번호 확인창 리셋
    }
    
    // 비밀번호 변경시 리셋
    function resetFunc() {
      pwCheckInput.value = "";
      pwCheckSpan.innerText = "";
    }
    
    // 비밀번호 6자 이상인가욤
    function pwLengthCheck() {
      if (pwInput.value.length < 6) {
        const pwLengthSpan = document.querySelector("#pwLengthSpan");
        pwLengthSpan.innerText = "비밀번호는 6자 이상 입력해주세요.";
      } else pwLengthSpan.innerText = "";
    }
    
    // 회원가입 정보 localStorage에 저장
    function signUp(event) {
      event.preventDefault();
    
      const nameInput = document.querySelector("#nameInput");
      const birthInput = document.querySelector("#birthInput");
    
      let obj = {};
    
      if (
        pwCheckSpan.innerText === PWOK_KEY &&
        idCheckSpan.innerText === IDOK_KEY
      ) {
        obj.id = idInput.value;
        obj.pw = pwInput.value;
        obj.name = nameInput.value;
        obj.birth = birthInput.value;
    
        localStorage.setItem("user", JSON.stringify(obj));
        alert("회원가입이 완료되었습니다!");
        window.location.assign("index.html");
      }
    }
    
    // Event Listner
    idInput.addEventListener("keyup", idCheck);
    
    pwCheckInput.addEventListener("keyup", pwCheck); // pw 똑같이 썼는지 체크
    
    pwInput.addEventListener("keydown", resetFunc); // pw 수정시 비밀번호 확인, 확인문구 초기화
    pwInput.addEventListener("keyup", pwLengthCheck);
    
    signUpForm.addEventListener("submit", signUp);

    signup.js

     


     

    깨달은 점 / 추가하고 싶은 것들

    1. html / css 에 서투르다.

    내 생각보다 html, css 지식이나 사용법이(?) 더~ 서툴러서 애먹었다. 자료참고+공부의 필요성을 격하게 느꼈다.

     

    2. 웹접근성에 대한 고민

    웹접근성을 높이는 시맨틱한 코드 짜기는 정말 어렵구나. 어렵다고 표현했지만 거의 ... 완벽하게 접근성 낮은 웹페이지가 만들어진 것 같다 (ㅎ..) 내가 아직 html css를 정확히 이해하지 못해서 더더욱 그런거겠지. 여기도 공부가 필요해 ~ 다음에 만들 건 좀 더 html css가 (아마도)중요해질테니 공식문서를 열심히 읽어가며 만들어봐야겠다.

     

    3. localStorage 잘못 알고 있던 지식 파악 후 수정

    localStorage에서 Key 값을 가져올 수 있을 거라고 잘못 이해하고 있었어서 키값을 아이디값으로 할당했는데 ... 그럴 필요가 없다는 걸 깨달아서 전면 수정했다 !! 덕분에 다음에는 헷갈리지 않을 수 있을 것 같다. 

     

    4. 애니메이션을 추가하고 싶었다.

    특히 로그인부분에서 비밀번호가 다를 때나 없는 아이디일 경우 input 창을 양옆으로 흔드는 애니메이션(?)을 만들고 싶었다.

    근데 최근 스크린리더에 관심이 생겨서 ... 스크린리더로 애니메이션을 읽어낼 수 있을지에 대한 의문이 생겨서 일단은 추가하지 않았다.

    이건 더 찾아봐야 할 것 같다. 내 검색 실력 문제인지 원하는 답이 안나온다 ㅠ_ㅠ.. 이 답을 찾아낸 다음에 나중에라도 애니메이션을 추가하고 싶다.

     

     

     

     

     

     

     

    댓글

Designed by Tistory.