JS/CSS DOM을 이용한 [회원가입 유효성검사]

2023. 1. 7. 02:16구현 결과물

구현화면

요즘 자꾸 작업을 하고나서 보면 핑크색으로 물들어있다.. 나 많이 아픈가?


Bare Minimum도 통과~!

코드

HTML

<!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="global-style.css" />
    <link rel="stylesheet" href="style2.css" />
    <link rel="icon" type="image/png" sizes="16x16"
        href="https://user-images.githubusercontent.com/104641096/169642850-921ac4a3-10d5-4462-a4c8-5aaf34a8931b.png">

</head>

<body>
    <SECTION CLASS="login_form">

        <h1><span style="color: #fa09c6">Blossom</h1>
        <form method="post" action="">
            <div class="int-area">
                <input type="id" name="id" id="username" autocomplete="off" required>
                <label for="username">USER NAME</label>
            </div>
            <div class="success-message hide">사용할 수 있는 아이디입니다</div>
            <div class="failure-message hide">아이디는 네 글자 이상이어야 합니다</div>
            <div class="onlyengnum-message hide">영어 또는 숫자만 입력 가능합니다.</div>



            <div class="int-area">
                <input type="password" name="pw" id="password" autocomplete="off" required>
                <label for="password">PASSWORD</label>
            </div>
            <div class="int-area">
                <input type="password" name="pw" id="password-retype" autocomplete="off" required>
                <label for="password-retype">RE-PASSWORD</label>
            </div>
            <div class="mismatch-message hide">비밀번호가 일치하지 않습니다</div>
            <div class="notstrong-message hide">최소 8자 이상,알파벳과 숫자 및 특수문자(@$!%*#?&)는 하나 이상 포함되어야 합니다.</div>
            <div class="btn-area">
                <button type="submit">Sing Up</a></button>
            </div>

            <script src="script.js"></script>
            </div>
        </form>

    </SECTION>
</body>

</html>

CSS

@import url('https://fonts.googleapis.com/css2?family=Do+Hyeon&family=Jua&display=swap');
@import url('https://fonts.googleapis.com/css2?family=Do+Hyeon&family=Jua&family=Roboto+Slab:wght@500&display=swap');
@import url('https://fonts.googleapis.com/css2?family=Black+Han+Sans&family=Do+Hyeon&family=Jua&family=Roboto+Slab:wght@500&display=swap');
@import url('https://fonts.googleapis.com/css2?family=Black+Han+Sans&family=Do+Hyeon&family=Gothic+A1:wght@500&family=Jua&family=Roboto+Slab:wght@500&display=swap');
@import url('https://fonts.googleapis.com/css2?family=Black+Han+Sans&family=Do+Hyeon&family=Gothic+A1:wght@500&family=Jua&family=Noto+Sans+KR:wght@500&family=Roboto+Slab:wght@500&display=swap');
@import url('https://fonts.googleapis.com/css2?family=Inspiration&display=swap');
@import url('https://fonts.googleapis.com/css2?family=Noto+Sans+KR:wght@500&display=swap');


* {margin: 0; padding: 0; box-sizing: border-box;}

body {
  font-family: 'Roboto Slab', serif;
  display: flex;
  justify-content: center;
  align-items: center;
  height: 100vh;
  background-position: center;
  background: url("https://user-images.githubusercontent.com/104641096/168153681-3de36068-1631-4ec2-a179-6ae02200edb1.jpg") no-repeat center;
  background-size: cover;

}
form {
    margin-top:35px
}
.login_form{
    position: relative;
    z-index: 2;
    border:1px solid red;
    height: 500px;
  width: 400px;
  padding: 24px;
  background: rgba( 232, 191, 237, 0.15 );
  box-shadow: rgba(240, 46, 170, 0.4) 5px 5px, rgba(240, 46, 170, 0.3) 10px 10px, rgba(240, 46, 170, 0.2) 15px 15px, rgba(240, 46, 170, 0.1) 20px 20px, rgba(240, 46, 170, 0.05) 25px 25px;
  backdrop-filter: blur( 0px );
  -webkit-backdrop-filter: blur( 0px );
  border-radius: 10px;
  border: 1px solid rgba( 255, 255, 255, 0.18 );

}

.login_form h1 {
    font-size: 32px; color: #ffffff;
    text-align: center;
    
}

.int-area {width: 400px; position: relative;}
.int-area input {
  width: 85%;
  padding: 20px 10px 10px;
  background-color: transparent;
  border: none;
  border-bottom: 2px solid rgb(39, 38, 38, 0.2);
  font-size: 18px;
  color: #020202;
  outline: none;
}

  .int-area label {
  position: absolute; left: 10px; top: 0px;
  font-size: 18px; color: #a09da0;
  transition: all .5s ease;
}
.int-area label.warning {
  color: whitesmoke !important;
  animation: warning .3s ease;
  animation-iteration-count: 3;
}
@keyframes warning{
  0% {transform: translateX(-8px);}
  25% {transform: translateX(8px);}
  50% {transform: translateX(-8px);}
  75% {transform: translateX(8px);}

}
.int-area input:focus + label,
.int-area input:valid + label {
    top: -2px;
  font-size: 13px; color: #000000;
}

span {
  font-family: 'Inspiration', cursive;
  text-align: center;
  font-size: 75px;
  margin: 30px 30px 30px 30px ;
  
}

.btn-area {margin-top: 30px;}
.btn-area button {

  width: 100%; height: 50px;
  font-family: 'Roboto Slab', serif;
  background-color: #fc63db;
  color: #ffffff;
  font-size: 20px;
  border: none;
  border-radius: 25px;
  cursor: pointer;
}

button:hover {
  background-color: #fa09c6;
}

input::placeholder{
  font-size:12px;
  padding-left: 10px;
}

#username {
  font-size:20px;
}

#password {
  font-size:20px;
}
#password-retype {
  font-size:20px;
}
input:focus {
  outline: none;
}

.hide {
  display: none;
}

.signup {
  border: none;
}

.mismatch-message {
  font-family: 'Noto Sans KR', sans-serif;
  color: red;
  font-size:12px
  
}
.notstrong-message {
  font-family: 'Noto Sans KR', sans-serif;
  color: red;
  font-size:12px
  
  
}
.success-message {
  font-family: 'Noto Sans KR', sans-serif;
  color: rgb(0, 0, 0);
  font-size:12px
}
.failure-message {
  font-family: 'Noto Sans KR', sans-serif;
  color: red;
  font-size:12px
}
.onlyengnum-message {
  font-family: 'Noto Sans KR', sans-serif;
  color: red;
  font-size:12px
}

Javascript

let elInputUsername = document.querySelector('#username')
let elFailureMessage = document.querySelector('.failure-message')
let elSuccessMessage = document.querySelector('.success-message')
let onlyEngNumMessage = document.querySelector('.onlyengnum-message')
let numFailureMessage = document.querySelector('.mismatch-message')
let notStrongMessage = document.querySelector('.notstrong-message')
let password1 = document.querySelector('#password')
let password2 = document.querySelector('#password-retype')
let pattern1 = /[~!@#$%^&*]/;
let pattern2 = /[0-9]/;
let pattern3 = /[a-zA-Z]/;
let idpattern1 = /[ㄱ-ㅎ가~힣]/


  




//-----------------------------------------------------------------------------------
elInputUsername.onkeyup = function () { //ID유효성 검사
if(elInputUsername.value.length === 0){
  elSuccessMessage.classList.add('hide')
  elFailureMessage.classList.add('hide')
  onlyEngNumMessage.classList.add('hide')
}else if(elInputUsername.value.length < 4 && elInputUsername.value.length >0){   
    elFailureMessage.classList.remove('hide')
  }else{
    elFailureMessage.classList.add('hide')
    elSuccessMessage.classList.remove('hide')
  }
  if(idpattern1.test(elInputUsername.value)||pattern1.test(elInputUsername.value)){
    onlyEngNumMessage.classList.remove('hide')
    elSuccessMessage.classList.add('hide')
  }else if (!idpattern1.test(elInputUsername.value)||!pattern1.test(elInputUsername.value)){
    onlyEngNumMessage.classList.add('hide') 
  }
}

//-----------------------------------------------------------------------------------

password2.onkeyup = function () { // 패스워드1 패스워드 2 중복 유효성검사
if(password1.value.length === 0 && password2.value.length === 0){
  numFailureMessage.classList.add('hide')
}else if (isMatch(password1.value, password2.value)) {
    numFailureMessage.classList.add('hide')
  } else {
    numFailureMessage.classList.remove('hide')
  }
}
function isMatch(password1, password2) {return password1 === password2}
  

//-----------------------------------------------------------------------------------

password1.onkeyup=function() { // 패스워드 특수문자/숫자/8글자 이상 확인 유효성검사
if(password1.value.length === 0 ){
  notStrongMessage.classList.add('hide')
}else if(pattern1.test(password1.value)&&pattern2.test(password1.value)&&pattern3.test(password1.value)&&password1.value.length >=8) {
   notStrongMessage.classList.add('hide')
  }else{
   notStrongMessage.classList.remove('hide')
  }
}
//-----------------------------------------------------------------------------------

느낀 점

js는 처음엔 구현이 막막하더라도 결국 정해진 기능을 구현만 하면 되지만, css의 경우 끝이랄게없고 욕심을 부리면 한도 끝도 없는 영역이라 더 어렵게 느껴졌다. 지금까지 script파일은 100% 외부 오픈소스를 가져왔는데 처음으로 내가 직접 짠 script로 구현을 해보니 뿌듯하기도 하고 아직 배울게 참 많다는 걸 느꼇다. 

핑크공주가 된 것 같아 살짝 찜찜하기도 하달까 ..