-
Notifications
You must be signed in to change notification settings - Fork 39
[배혜민] sprint4 #155
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
The head ref may contain hidden characters: "Basic-\uBC30\uD61C\uBBFC-sprint4"
[배혜민] sprint4 #155
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,50 @@ | ||
| <!DOCTYPE html> | ||
| <html lang="en"> | ||
| <head> | ||
| <meta charset="UTF-8"> | ||
| <meta name="viewport" content="width=device-width, initial-scale=1.0"> | ||
| <title>판다마켓 회원가입</title> | ||
| <link rel="stylesheet" href="reset.css"> | ||
| <link rel="stylesheet" href="sub.css"> | ||
| <script src="./js/input.js"></script> | ||
| </head> | ||
| <body> | ||
| <div class="join_box"> | ||
| <h1 class="logo"> | ||
| <img src="./images/join_logo.png" alt="판다마켓"> | ||
| </h1> | ||
| <form action="join"> | ||
| <div class="form_box"> | ||
| <label for="email">이메일</label> | ||
| <input id="email" type="email" name="email" placeholder="[email protected]" required> | ||
| </div> | ||
| <p class="wraing">이메일을 입력해주세요</p> | ||
| <div class="form_box"> | ||
| <label for="name">닉네임</label> | ||
| <input type="text" name="name"> | ||
| </div> | ||
| <div class="form_box"> | ||
| <label for="password">비밀번호</label> | ||
| <input id="password" type="password" name="password"> | ||
| </div> | ||
| <p class="wraing">비밀번호를 입력해주세요</p> | ||
| <div class="form_box"> | ||
| <label for="password">비밀번호 확인</label> | ||
| <input id="password2" type="password" name="password"> | ||
| </div> | ||
| <p class="wraing">비밀번호를 입력해주세요</p> | ||
| <button id="login_btn" class="join_btn gray">회원가입</button> | ||
| </form> | ||
| <div class="login_banner"> | ||
| <p>간편 로그인하기</p> | ||
| <a href="https://www.google.com/" class="google_login"> | ||
| <img src="./images/google_icon.png" alt="구글 로그인하기"> | ||
| </a> | ||
| <a href="https://www.kakaocorp.com/page/" class="kakao_login"> | ||
| <img src="./images/kakao_icon.png" alt="카카오 로그인하기"> | ||
| </a> | ||
| </div> | ||
| <p class="login_txt">이미 회원이신가요? <a href="login.html">로그인</a></p> | ||
| </div> | ||
| </body> | ||
| </html> |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,104 @@ | ||
| document.addEventListener("DOMContentLoaded", function () { | ||
| const emailInput = document.getElementById("email"); | ||
| const passWord = document.getElementById("password"); | ||
| const passWord2 = document.getElementById("password2"); | ||
| const loginBtn = document.getElementById("login_btn"); | ||
| const wraingAll = document.querySelectorAll(".wraing"); | ||
|
|
||
| emailInput.addEventListener("focusout",function(){ | ||
|
|
||
| let par = emailInput.parentNode | ||
| let wraing = par.nextElementSibling; | ||
| let emailValue = emailInput.value | ||
| let emailVaild = /^[^\s@]+@[^\s@]+\.[^\s@]+$/; | ||
|
|
||
| if(emailValue.length === 0){ | ||
| emailInput.classList.add("on"); | ||
| loginBtn.classList.add("gray"); | ||
| wraing.classList.add("on"); | ||
| wraing.textContent = "이메일을 입력해주세요."; | ||
| }else if(!emailVaild.test(emailValue)){ | ||
| emailInput.classList.add("on"); | ||
| loginBtn.classList.add("gray"); | ||
| wraing.classList.add("on"); | ||
| wraing.textContent = "잘못된 이메일 형식입니다."; | ||
| }else{ | ||
| emailInput.classList.remove("on"); | ||
| wraing.classList.remove("on"); | ||
|
|
||
| let hasOnClass = false; | ||
| wraingAll.forEach(function (el) { | ||
| if (el.classList.contains("on")) { | ||
| hasOnClass = true; | ||
| } | ||
| }); | ||
|
|
||
| if (!hasOnClass) { | ||
| loginBtn.classList.remove("gray"); | ||
| } | ||
| } | ||
|
Comment on lines
+15
to
+39
Collaborator
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. if문 뎁스가 깊어요. 예시를 보여드릴게요 :) // 상태 관리 객체
const loginState = {
email: {
value: '',
isValid: false,
errors: {
empty: false,
invalid: false
}
},
password: {
value: '',
isValid: false,
errors: {
empty: false,
invalid: false
}
},
isPasswordVisible: false,
isFormValid: false
};
Collaborator
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. function validateForm() {
// 이메일 검증
const emailValue = emailInput.value.trim();
loginState.email.errors.empty = emailValue === '';
loginState.email.errors.invalid = !loginState.email.errors.empty && !isValidEmail(emailValue);
loginState.email.isValid = !loginState.email.errors.empty && !loginState.email.errors.invalid;
// 비밀번호 검증
const passwordValue = passwordInput.value;
loginState.password.errors.empty = passwordValue === '';
loginState.password.errors.invalid = !loginState.password.errors.empty && passwordValue.length < 8;
loginState.password.isValid = !loginState.password.errors.empty && !loginState.password.errors.invalid;
// 전체 폼 유효성
loginState.isFormValid = loginState.email.isValid && loginState.password.isValid;
// UI 업데이트
updateUI();
return loginState.isFormValid;
}
Collaborator
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 유효성 검사 수행의 경우에도 관련있는 로직끼리 모아주기위해 이런식으로 구조를 바꿔보면 어떨까요? export const validators = {
email: (value) => {
if (!value) return { isValid: false, message: "이메일을 입력해주세요" };
if (!/^[^\s@]+@[^\s@]+\.[^\s@]+$/.test(value)) {
return { isValid: false, message: "올바른 이메일 형식이 아닙니다" };
}
return { isValid: true, message: "" };
},
password: (value) => {
if (!value) return { isValid: false, message: "비밀번호를 입력해주세요" };
if (value.length < 8) {
return { isValid: false, message: "비밀번호는 8자 이상이어야 합니다" };
}
return { isValid: true, message: "" };
},
};
Collaborator
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 이렇게 구조를 바꿔보면 이런 장점이 생기겠죠?
|
||
|
|
||
| }); | ||
|
|
||
| passWord.addEventListener("focusout",function(){ | ||
| let loginBtn = document.getElementById("login_btn"); | ||
| let par = passWord.parentNode | ||
| let wraing = par.nextElementSibling; | ||
| if(passWord.value.length == 0){ | ||
| passWord.classList.add("on"); | ||
| wraing.classList.add("on"); | ||
|
Comment on lines
+47
to
+49
Collaborator
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 이런식으로 UI를 업데이트하는것도, 매번 이런식으로 직접적으로 DOM에 접근해 조작하는것보다, 상태 관리 목적으로 쓰이는 객체의 값에 맞춰 DOM을 조작하는식으로 바꿔보면 추후에 코드를 수정하거나 확장할때 용이해지겠죠? :) |
||
| wraing.textContent = "비밀번호를 입력해주세요"; | ||
| loginBtn.classList.add("gray"); | ||
| }else if(passWord.value.length < 8){ | ||
| passWord.classList.add("on"); | ||
| wraing.classList.add("on"); | ||
| wraing.textContent = "비밀번호를 8자 이상 입력해주세요."; | ||
| loginBtn.classList.add("gray"); | ||
| }else{ | ||
| passWord.classList.remove("on"); | ||
| wraing.classList.remove("on"); | ||
|
|
||
| let hasOnClass = false; | ||
| wraingAll.forEach(function (el) { | ||
| if (el.classList.contains("on")) { | ||
| hasOnClass = true; | ||
| } | ||
| }); | ||
| if (!hasOnClass) { | ||
| loginBtn.classList.remove("gray"); | ||
| } | ||
| } | ||
| }); | ||
|
|
||
| passWord2.addEventListener("focusout",function(){ | ||
| let loginBtn = document.getElementById("login_btn"); | ||
| let par = passWord2.parentNode | ||
| let wraing = par.nextElementSibling; | ||
| if(passWord2.value.length == 0){ | ||
| passWord2.classList.add("on"); | ||
| wraing.classList.add("on"); | ||
| wraing.textContent = "비밀번호를 입력해주세요"; | ||
| loginBtn.classList.add("gray"); | ||
| }else if(passWord.value == passWord2.value){ | ||
| passWord2.classList.add("on"); | ||
| wraing.classList.add("on"); | ||
| wraing.textContent = "“비밀번호가 일치하지 않습니다."; | ||
| loginBtn.classList.add("gray"); | ||
| }else{ | ||
| passWord2.classList.remove("on"); | ||
| wraing.classList.remove("on"); | ||
|
|
||
| let hasOnClass = false; | ||
| wraingAll.forEach(function (el) { | ||
| if (el.classList.contains("on")) { | ||
| hasOnClass = true; | ||
| } | ||
| }); | ||
| if (!hasOnClass) { | ||
| loginBtn.classList.remove("gray"); | ||
| } | ||
| } | ||
| }); | ||
|
|
||
|
|
||
| }); | ||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,41 @@ | ||
| <!DOCTYPE html> | ||
| <html lang="en"> | ||
| <head> | ||
| <meta charset="UTF-8"> | ||
| <meta name="viewport" content="width=device-width, initial-scale=1.0"> | ||
| <title>판다마켓 로그인</title> | ||
| <link rel="stylesheet" href="reset.css"> | ||
| <link rel="stylesheet" href="sub.css"> | ||
| <script src="./js/input.js"></script> | ||
| </head> | ||
| <body> | ||
| <div class="join_box"> | ||
| <h1 class="logo"> | ||
| <img src="./images/join_logo.png" alt="판다마켓"> | ||
| </h1> | ||
| <form action="join"> | ||
| <div class="form_box"> | ||
| <label for="email">이메일</label> | ||
| <input id="email" type="email" name="email" placeholder="[email protected]" required> | ||
| </div> | ||
| <p class="wraing">이메일을 입력해주세요</p> | ||
| <div class="form_box"> | ||
| <label for="password">비밀번호</label> | ||
| <input id="password" type="password" name="password"> | ||
| </div> | ||
| <p class="wraing">비밀번호를 입력해주세요</p> | ||
| <button id="login_btn" class="join_btn gray">로그인</button> | ||
| </form> | ||
| <div class="login_banner"> | ||
| <p>간편 로그인하기</p> | ||
| <a href="https://www.google.com/" class="google_login"> | ||
| <img src="./images/google_icon.png" alt="구글 로그인하기"> | ||
| </a> | ||
| <a href="https://www.kakaocorp.com/page/" class="kakao_login"> | ||
| <img src="./images/kakao_icon.png" alt="카카오 로그인하기"> | ||
| </a> | ||
| </div> | ||
| <p class="login_txt">이미 회원이신가요? <a href="login.html">로그인</a></p> | ||
| </div> | ||
| </body> | ||
| </html> |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
해당 함수에서 너무 많은 일을 하고있어 가독성 측면에서 좋지않고, 유지보수가 힘들어질거예요.
기존의 이벤트 리스너 연결 방식은 그대로 유지하되, 콜백함수에서 모든 일을 처리하는게 아니라 함수가 하나의 일만 담당할수있게끔 분리해보는것부터 시작할까요?