[TIL] UDR 2023 FE - 006

You Seunghyeon·2023년 5월 19일
0

TIL

목록 보기
5/8

오늘은 그동안 학습했던 내용을 바탕으로 쿠팡 로그인페이지 클론코딩을 진행했다. 원래 수업에서는 기본적으로 CSS 요소의 이름이 작성된 내용을 제공했지만, 처음부터 직접 구성해보고 싶었기에 개인적으로 코드를 직접 구성했다.

원래 수업 목표에서는 JS로 input 값이 비었을경우 색상 변경 정도만 진행하는 코드였지만, 추가적으로 input 값이 정확하게 입력되었는지 검증하는 validation 단계를 추가했다.

현재 코드는 작성중이며, 코드는 아래와 같다.

index.html

<!doctype html>
<html lang="ko">
<head>
  <meta charset="UTF-8">
  <meta name="viewport"
        content="width=device-width, user-scalable=no, initial-scale=1.0, maximum-scale=1.0, minimum-scale=1.0">
  <meta http-equiv="X-UA-Compatible" content="ie=edge">
  <link rel="stylesheet" href="./css/style.css">
  <script src="./js/main.js"></script>
  <title>로그인</title>
</head>
<body>

<div class="wrapper">

  <a href="//www.coupang.com/" class="logo-area">
    <img src="./resource/img/logo-coupang.png" alt="Coupang" class="logo">
  </a>

  <form action="//api.domain.com/v1/user/login/" method="POST" class="login">
    <div class="login-area">
      <label for="login-email" class="login-input-wrapper">
        <span class="icon-wrapper"><i class="icon icon-email"></i></span>
        <input type="email" class="login-input" id="login-email"
               placeholder="아이디(이메일)"
               maxlength="80">
      </label>
      <span class="input-check-msg" id="login-email-msg"></span>
      <label for="login-password" class="login-input-wrapper">
        <span class="icon-wrapper"><i class="icon icon-password"></i></span>
        <input type="password" class="login-input" id="login-password"
               placeholder="비밀번호"
               maxlength="80">
      </label>
      <span class="input-check-msg" id="login-password-msg"></span>
    </div>
  </form>

</div>

</body>
</html>

css/style.css

html, body {
    margin: 0;
    padding: 0;
}

* {
    box-sizing: border-box;
}

.wrapper {
    margin: 0 auto;
    text-align: center;
    padding-left: 20px;
    padding-right: 20px;
    padding-top: 48px;

    max-width: 460px;
    min-width: 290px;
}

.logo {
    width: 100%;
    max-width: 195px;
    min-width: 127px;
    height: auto;
}

.login-input-wrapper {
    margin-top: 14px;
    width: 100%;
    display: block;
    height: 48px;
    border: 1px solid #CCCCCC;
    box-sizing: content-box;
    transition: border 0.1s linear;
}

.login-area .icon-wrapper {
    display: inline-block;
    box-sizing: border-box;
    float: left;
    position: relative;
    width: 45px;
    height: 48px;
    background-color: #fafafa;
    border-right: 1px solid #CCCCCC;
    z-index: -1;
}

.icon {
    background-image: url(/resource/img/sprite-member.svg), none;
    background-size: 148px 148px;
    position: absolute;
    display: inline-block;
    top: 50%;
    margin-left: -10px;
    vertical-align: middle;
}

.icon-email {
    background-position: -1px -1px;
    margin-top: -8px;
    height: 16px;
    padding-left: 20px;
}

.icon-password {
    background-position: -22px -1px;
    margin-top: -10px;
    height: 20px;
    padding-left: 20px;
}

.login-input {
    display: inline-block;
    position: relative;
    width: calc(100% - 45px);
    height: 100%;
    color: #111;
    padding: 16px 0px;
    font-weight: 700;
    text-indent: 12px;
    margin: 0;
    border: 0;
}

.login-input:focus {
    outline: none;
}

.login-input-wrapper:focus-within {
    border-bottom: 2px solid #346aff;
}

.login-input-wrapper:has(:invalid),
.input-invalid {
    border-bottom: 2px solid #e7223d;
}

.login-input::placeholder {
    font-family: dotum,sans-serif;
    font-size: 12px;
    line-height: 1.6;
    color: #AAAAAA;
}

.input-check-msg {
    display: block;
    margin: 9px 12px 0;
    padding: 0;
    font-family: dotum,sans-serif;
    font-size: 12px;
    line-height: 18px;
    text-align: left;
}

.msg-error {
    color: #e7223d;
}

js/main.js

window.onload = function () {
  const input_email = document.getElementById("login-email");
  const input_email_msg = document.getElementById("login-email-msg");
  const input_password = document.getElementById("login-password");
  const input_check_msg = document.getElementsByClassName("input-check-msg");

  const email_validate_regex = "/^[0-9a-zA-Z]([-_.]?[0-9a-zA-Z])*@[0-9a-zA-Z]([-_.]?[0-9a-zA-Z])*.[a-zA-Z]{2,3}$/i";

  const validate_email = (value) => {
    const isEmpty = value == "";
    const isEmailFormat = value.match(email_validate_regex);

    if (isEmpty || !isEmailFormat) {
      input_email.parentElement.classList.add("input-invalid");
      input_email_msg.classList.add("msg-error");
    } else {
      input_email.parentElement.classList.remove("input-invalid");
    }

    if (isEmpty) {
      console.log("rk")
      input_email_msg.textContent = "아이디(이메일)를 입력해주세요.";
    } else if (!isEmailFormat) {
      input_email_msg.textContent = "아이디(이메일)는 이메일 형식으로 입력해주세요.";
    }
  }

  const validate_password = (value) => {
    // codes
  }

  input_email.addEventListener("focusout", (event) => {
    validate_email(input_email.value);
  });
}

0개의 댓글