JS/CSS DOM을 이용한 [회원가입 유효성검사]
2023. 1. 7. 02:16ㆍ구현 결과물
구현화면
코드
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로 구현을 해보니 뿌듯하기도 하고 아직 배울게 참 많다는 걸 느꼇다.
핑크공주가 된 것 같아 살짝 찜찜하기도 하달까 ..
'구현 결과물' 카테고리의 다른 글
API로 부터 항공편을 받아와 조회하기 (0) | 2023.02.04 |
---|---|
축하받고 싶어서 급하게 만든 나의 축하 게시판! (0) | 2023.02.02 |
React state & props (0) | 2023.01.28 |
React Tweettler Bare Minimum Requirement 및 useNavigate 구현 (0) | 2023.01.24 |
나만의 아고라스테이츠 만들기 ing... (0) | 2023.01.11 |