-
Notifications
You must be signed in to change notification settings - Fork 39
[김태일] Sprint4 #161
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-\uAE40\uD0DC\uC77C-sprint4"
[김태일] Sprint4 #161
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 |
|---|---|---|
|
|
@@ -24,13 +24,18 @@ <h1>판다마켓</h1> | |
| <form> | ||
| <div class="group"> | ||
| <label for="email">이메일</label> | ||
| <input type="email" id="email" name="email"> | ||
| <input type="email" id="email" name="email" placeholder="이메일을 입력해주세요." | ||
| class="error-input"> | ||
| <p id="emailErr" class="errMsg">잘못된 이메일 형식입니다</p> | ||
|
|
||
| </div> | ||
| <div class="group"> | ||
| <label for="password">비밀번호</label> | ||
| <div class="password-input"> | ||
| <input type="password" id="password" name="password"> | ||
| <input type="password" id="password" name="password" placeholder="비밀번호를 입력해주세요."> | ||
|
|
||
| <img src="./image/invisible_icon.png" class="password-icon" alt="비밀번호 보기"> | ||
| <p id="passwordErr" class="errMsg">비밀번호를 8자 이상 입력해주세요.</p> | ||
| </div> | ||
| </div> | ||
| <button type="submit">로그인</button> | ||
|
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. ❗️ 수정요청 |
||
|
|
@@ -51,12 +56,12 @@ <h1>간편 로그인하기</h1> | |
|
|
||
| </div> | ||
| <div class="footer"> | ||
| <h1>판다마켓이 처음이신가요?</h1> | ||
| <p>판다마켓이 처음이신가요?</p> | ||
| <a href="./signup.html">회원가입</a> | ||
| </div> | ||
|
|
||
|
|
||
| </div> | ||
|
|
||
| <script src="./sign-in.js"></script> | ||
|
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. 💊 제안 아마 script 태그를 HTML의 하단에 배치하신 이유가 script가 문서의 렌더링을 막지 않도록 하기 위해서이실 것 같아요. 지금과 같은 경우 DOM을 조작하는 JS 이니 defer 속성을 추가하시면 되겠습니다~ |
||
| </body> | ||
| </html> | ||
|
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. 💊 제안 |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,85 @@ | ||
| /* login, signup 공통 */ | ||
|
|
||
| // 이메일 유효성 검사 함수 | ||
| function emailValidation(email) { | ||
| const emailRegex = /^[a-zA-Z0-9._%+-]+@[a-zA-Z0-9.-]+\.[a-zA-Z]{2,}$/; | ||
| return emailRegex.test(email); | ||
| } | ||
|
Comment on lines
+4
to
+7
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. 💊 제안 |
||
|
|
||
| // 요소 가져오기 | ||
| const emailInput = document.getElementById("email"); | ||
| const passwordInput = document.getElementById("password"); | ||
| const emailErr = document.getElementById("emailErr"); | ||
| const passwordErr = document.getElementById("passwordErr"); | ||
| const passwordVisibility = document.getElementById("passwordVisibility"); | ||
|
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. 💊 제안 |
||
|
|
||
| // 초기 오류 메시지 숨김 | ||
| emailErr.textContent = ""; | ||
| passwordErr.textContent = ""; | ||
|
|
||
| // 이메일 검증 | ||
| function validateEmail() { | ||
| const emailValue = emailInput.value.trim(); | ||
| if (emailValue === "") { | ||
| emailErr.textContent = "이메일을 입력해주세요."; | ||
| emailInput.classList.add("error-input"); | ||
| emailInput.classList.remove("correct-input"); | ||
| } else if (!emailValidation(emailValue)) { | ||
| emailErr.textContent = "잘못된 이메일 형식입니다."; | ||
| emailInput.classList.add("error-input"); | ||
| emailInput.classList.remove("correct-input"); | ||
| } else { | ||
| emailErr.textContent = ""; | ||
| emailInput.classList.remove("error-input"); | ||
| emailInput.classList.add("correct-input"); | ||
| } | ||
| toggleButton(); | ||
| } | ||
|
|
||
| // 비밀번호 검증 | ||
| function validatePassword() { | ||
| const passwordValue = passwordInput.value.trim(); | ||
| if (passwordValue === "") { | ||
| passwordErr.textContent = "비밀번호를 입력해주세요."; | ||
| passwordInput.classList.add("error-input"); | ||
| passwordInput.classList.remove("correct-input"); | ||
| } else if (passwordValue.length < 8) { | ||
| passwordErr.textContent = "비밀번호를 8자 이상 입력해주세요."; | ||
| passwordInput.classList.add("error-input"); | ||
| passwordInput.classList.remove("correct-input"); | ||
| } else { | ||
| passwordErr.textContent = ""; | ||
| passwordInput.classList.remove("error-input"); | ||
| passwordInput.classList.add("correct-input"); | ||
| } | ||
| toggleButton(); | ||
| } | ||
|
|
||
| // 비밀번호 보이기/숨기기 기능 | ||
| function togglePasswordVisibility(input, button) { | ||
| if (input.type === "password") { | ||
| input.type = "text"; | ||
| button.innerHTML = '<img src="/images/eye-icon.png" class="eye-icon" alt="eye-off">'; | ||
| } else { | ||
| input.type = "password"; | ||
| button.innerHTML = '<img src="/images/invisible-eye-icon.png" class="eye-icon" alt="eye-on">'; | ||
| } | ||
| } | ||
|
|
||
| // 이벤트 리스너 추가 | ||
| emailInput.addEventListener("focusout", validateEmail); | ||
| passwordInput.addEventListener("focusout", validatePassword); | ||
| passwordVisibility.addEventListener("click", () => togglePasswordVisibility(passwordInput, passwordVisibility)); | ||
|
|
||
| // 엔터 키 입력 시 검증 함수 실행 | ||
| emailInput.addEventListener("keydown", function(event) { | ||
| if (event.key === "Enter") { | ||
| validateEmail(); | ||
| } | ||
| }); | ||
|
|
||
| passwordInput.addEventListener("keydown", function(event) { | ||
| if (event.key === "Enter") { | ||
| validatePassword(); | ||
| } | ||
| }); | ||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,133 @@ | ||
| /* login, signup 공통 */ | ||
|
|
||
| // 이메일 유효성 검사 함수 | ||
| function emailValidation(email) { | ||
| const emailRegex = /^[a-zA-Z0-9._%+-]+@[a-zA-Z0-9.-]+\.[a-zA-Z]{2,}$/; | ||
| return emailRegex.test(email); | ||
| } | ||
|
|
||
| // 요소 가져오기 | ||
| const emailInput = document.getElementById("email"); | ||
| const passwordInput = document.getElementById("password"); | ||
| const passwordRepeatInput = document.getElementById("password-repeat"); | ||
| const emailErr = document.getElementById("emailErr"); | ||
| const passwordErr = document.getElementById("passwordErr"); | ||
| const passwordCheckErr = document.getElementById("passwordCheckErr"); | ||
| const passwordVisibility = document.getElementById("passwordVisibility"); | ||
|
|
||
| let isPasswordCheckTouched = false; // 비밀번호 확인 입력 여부 추적 | ||
|
|
||
| // 초기 오류 메시지 숨김 | ||
| emailErr.style.display = "none"; | ||
| passwordErr.style.display = "none"; | ||
| passwordCheckErr.style.display = "none"; | ||
|
|
||
| // 이메일 검증 | ||
| function validateEmail() { | ||
| const emailValue = emailInput.value.trim(); | ||
| if (emailValue === "") { | ||
| emailErr.textContent = "이메일을 입력해주세요."; | ||
| emailErr.style.display = "block"; | ||
| emailInput.classList.add("error-input"); | ||
| emailInput.classList.remove("correct-input"); | ||
| } else if (!emailValidation(emailValue)) { | ||
| emailErr.textContent = "잘못된 이메일 형식입니다."; | ||
| emailErr.style.display = "block"; | ||
| emailInput.classList.add("error-input"); | ||
| emailInput.classList.remove("correct-input"); | ||
| } else { | ||
| emailErr.style.display = "none"; | ||
| emailInput.classList.remove("error-input"); | ||
| emailInput.classList.add("correct-input"); | ||
| } | ||
| toggleButton(); | ||
| } | ||
|
|
||
| // 비밀번호 검증 | ||
| function validatePassword() { | ||
| const passwordValue = passwordInput.value.trim(); | ||
| if (passwordValue === "") { | ||
| passwordErr.textContent = "비밀번호를 입력해주세요."; | ||
| passwordErr.style.display = "block"; | ||
| passwordInput.classList.add("error-input"); | ||
| passwordInput.classList.remove("correct-input"); | ||
| } else if (passwordValue.length < 8) { | ||
| passwordErr.textContent = "비밀번호를 8자 이상 입력해주세요."; | ||
| passwordErr.style.display = "block"; | ||
| passwordInput.classList.add("error-input"); | ||
| passwordInput.classList.remove("correct-input"); | ||
| } else { | ||
| passwordErr.style.display = "none"; | ||
| passwordInput.classList.remove("error-input"); | ||
| passwordInput.classList.add("correct-input"); | ||
| } | ||
| toggleButton(); | ||
| } | ||
|
|
||
| // 비밀번호 확인 검증 | ||
| function validatePasswordCheck() { | ||
| const passwordValue = passwordInput.value.trim(); | ||
| const passwordCheckValue = passwordRepeatInput.value.trim(); | ||
|
|
||
| if (!isPasswordCheckTouched) { | ||
| passwordCheckErr.style.display = "none"; // 입력 전에는 오류 문구 숨김 | ||
| return; | ||
| } | ||
|
|
||
| if (passwordCheckValue === "") { | ||
| passwordCheckErr.style.display = "none"; // 비밀번호 확인 필드가 비었을 때도 오류 메시지 숨김 | ||
| } else if (passwordValue !== passwordCheckValue) { | ||
| passwordCheckErr.textContent = "비밀번호가 일치하지 않습니다."; | ||
| passwordCheckErr.style.display = "block"; | ||
| passwordRepeatInput.classList.add("error-input"); | ||
| } else { | ||
| passwordCheckErr.style.display = "none"; | ||
| passwordRepeatInput.classList.remove("error-input"); | ||
| } | ||
| toggleButton(); | ||
| } | ||
|
|
||
| // 비밀번호 보이기/숨기기 기능 | ||
| function togglePasswordVisibility(input, button) { | ||
| if (input.type === "password") { | ||
| input.type = "text"; | ||
| button.innerHTML = '<img src="/images/eye-icon.png" class="eye-icon" alt="eye-off">'; | ||
| } else { | ||
| input.type = "password"; | ||
| button.innerHTML = '<img src="/images/invisible-eye-icon.png" class="eye-icon" alt="eye-on">'; | ||
| } | ||
| } | ||
|
|
||
| // 회원가입 버튼 활성화 | ||
| function toggleButton() { | ||
| const isFormValid = | ||
| emailErr.style.display === "none" && | ||
| passwordErr.style.display === "none" && | ||
| passwordCheckErr.style.display === "none" && | ||
| emailInput.value.trim() !== "" && | ||
| passwordInput.value.trim() !== "" && | ||
| passwordRepeatInput.value.trim() !== ""; | ||
|
|
||
| const signupButton = document.querySelector(".signup"); | ||
| if (isFormValid) { | ||
| signupButton.disabled = false; | ||
| signupButton.classList.add("active"); | ||
| } else { | ||
| signupButton.disabled = true; | ||
| signupButton.classList.remove("active"); | ||
| } | ||
|
Comment on lines
+111
to
+118
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. 💊 제안 const signupButton = document.querySelector(".signup");
signupButton.disabled = !isFormValid;
signupButton.classList.toggle("active", isFormValid); |
||
| } | ||
|
|
||
| // 이벤트 리스너 추가 | ||
| emailInput.addEventListener("focusout", validateEmail); | ||
| passwordInput.addEventListener("focusout", validatePassword); | ||
| passwordRepeatInput.addEventListener("input", () => { | ||
| isPasswordCheckTouched = true; // 사용자가 입력 시작했음을 추적 | ||
| validatePasswordCheck(); // 입력 시에도 검증 함수 실행 | ||
| }); | ||
| passwordRepeatInput.addEventListener("keydown", function(event) { | ||
| if (event.key === "Enter") { | ||
| validatePasswordCheck(); | ||
| } | ||
| }); | ||
| passwordVisibility.addEventListener("click", () => togglePasswordVisibility(passwordInput, passwordVisibility)); | ||
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.
💊 제안
미리 에러 메시지가 나타날 태그를 만들어 주셔서 DOM 조작을 최소화하신 점은 좋습니다!
다만 에러 메시지는 에러 상황에 따라 추가되도록 하는 것이 더 명확할 것 같아요!
지금처럼 미리 메시지가 들어가 있는 경우는 에러 나는 경우가 하나인 경우에 적절할 것 같습니다.