-
Notifications
You must be signed in to change notification settings - Fork 35
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
[손재헌] sprint4 #106
The head ref may contain hidden characters: "Basic-\uC190\uC7AC\uD5CC-sprint4"
[손재헌] sprint4 #106
Changes from all commits
6218f55
ee33de9
fd28b82
36053db
0789cf1
6aa4fdb
0e2c90a
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 |
---|---|---|
|
@@ -8,30 +8,43 @@ | |
</head> | ||
<body> | ||
<header> | ||
<a class="home-logo" href="/"><img class="header-img" src=../imgs/signup_logo.png></a> | ||
<a class="home-logo" href="/"><img class="header-img" src=../imgs/signup_logo.png alt="홈으로"></a> | ||
</header> | ||
<main> | ||
<div class="container"> | ||
<form> | ||
<label for="email">이메일</label> | ||
<div class="pseudo-form"> | ||
|
||
<label for="email"> | ||
이메일 | ||
<span class="email-empty error-message hidden">이메일을 입력해주세요.</span> | ||
<span class="email-wrong-format error-message hidden">잘못된 이메일 형식입니다.</span> | ||
</label> | ||
<input id="email" name="email" class="text-input" placeholder="이메일을 입력해주세요"> | ||
<label for="password">비밀번호</label> | ||
|
||
Comment on lines
+17
to
+23
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. 제 생각에는 에러메세지는 의미적으로 라벨과 상관이 없다고 생각합니다. 재헌님께서 에러메세지를 그렇다면 라벨과 인풋을 div로 감싸는 마크업을 더 낫다고 생각이 듭니다. <div>
<label for="email"> 이메일 </label>
<input
id="email"
name="email"
class="text-input"
placeholder="이메일을 입력해주세요"
/>
<span class="email-empty error-message hidden"
>이메일을 입력해주세요.</span
>
<span class="email-wrong-format error-message hidden"
>잘못된 이메일 형식입니다.</span
>
</div> |
||
<label for="password"> | ||
비밀번호 | ||
<span class="password-empty error-message hidden">비밀번호를 입력해주세요.</span> | ||
<span class="password-wrong-format error-message hidden">비밀번호를 8자 이상 입력해주세요.</span> | ||
</label> | ||
<div class="password-field"> | ||
<input id="password" name="password" class="text-input" type="password" placeholder="비밀번호를 입력해주세요"> | ||
<img src="../imgs/EyeIconSlashed.png" class="password-visibility-icon"> | ||
<img src="../imgs/EyeIconSlashed.png" class="password-visibility-icon" alt="패스워드 보이기"> | ||
|
||
</div> | ||
<button class="doit">로그인</button> | ||
<button class="login action-button">로그인</button> | ||
|
||
<div class="easy-login"> | ||
<span>간편 로그인하기</span> | ||
<div class="media-icons"> | ||
<a href="https://www.google.com/"><img src="../imgs/Component2.png"></a> | ||
<a href="https://www.kakaocorp.com/page/"><img src="../imgs/Component3.png"></a> | ||
<a href="https://www.google.com/"><img src="../imgs/Component2.png" alt="Google"></a> | ||
<a href="https://www.kakaocorp.com/page/"><img src="../imgs/Component3.png" alt="Kakao"></a> | ||
</div> | ||
</div> | ||
</form> | ||
|
||
</div> | ||
<span class=signup-link>판다마켓이 처음이신가요? <a href="/signup">회원가입</a></span> | ||
</div> | ||
</main> | ||
<script type="module" src="../scripts/signupIndex.js"></script> | ||
<script type="module" src="../scripts/signupEventHandler.js"></script> | ||
</body> | ||
</html> |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,17 +1,21 @@ | ||
// 조건이 충족되면 회색 버튼을 파란색으로 보이게 합니다. | ||
// 조건은 validChecklist에 배열로 각 함수값들을 저장해 확인합니다. | ||
// validChecklist의 원소들이 모두 true라면 버튼을 파란색으로 만듭니다. | ||
// 버튼 작동 조건을 최종적으로 확인하는 스크립트이기 때문에 버튼이 동작하는데 필요한 요건들을 확인하는 함수들은 모두 여기에서 실행합니다. | ||
|
||
const btn = document.querySelector('.doit'); | ||
// 모든 input에 값이 있고, 모든 input에 errored 클래스가 없을때 작동합니다. | ||
// 조건을 만족하면 버튼에 valid 클래스가 추가돼 파란색이 되고 disabled가 해제됩니다. | ||
|
||
import { inputs, btn } from "./constLib.js"; | ||
import filledInputCheck from "./filledInputsCheck.js"; | ||
import passwordVerifiedCheck from "./passwordVerifiedCheck.js"; | ||
|
||
export default function btnValidCheck() { | ||
const validChecklist = [filledInputCheck(), passwordVerifiedCheck()]; // 함수가 호출될때마다 배열 안의 함수들을 실행합니다. | ||
|
||
validChecklist.every((e) => e === true) | ||
? btn.classList.add('valid') | ||
: btn.classList.remove('valid'); | ||
const isValid = [...inputs].every(e => !e.classList.contains('errored')) && filledInputCheck(); // 모든 input에 errored 클래스가 없다 && 모든 input에 값이 있다 | ||
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 (isValid) { | ||
btn.classList.add('valid'); | ||
btn.disabled = false; | ||
return; | ||
} | ||
|
||
btn.classList.remove('valid'); | ||
btn.disabled = true; | ||
|
||
} |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,16 @@ | ||
const form = document.querySelector('.pseudo-form'); | ||
const inputs = document.querySelectorAll('input'); | ||
const btn = document.querySelector('.action-button'); | ||
|
||
const emailInput = document.querySelector('#email'); | ||
const nicknameInput = document.querySelector('#nickname'); | ||
const passwordInput = document.querySelector('#password'); | ||
const verifyPasswordInput = document.querySelector('#verify-password'); | ||
|
||
const loginPage = '/login'; | ||
const itemsPage = '/items'; | ||
|
||
const loginButtonLink = '/items'; | ||
const signupButtonLink = '/signup'; | ||
|
||
export { form, inputs, btn, emailInput, nicknameInput, passwordInput, verifyPasswordInput, loginPage, itemsPage, loginButtonLink, signupButtonLink }; |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,21 @@ | ||
import { emailInput, btn } from "./constLib.js"; | ||
|
||
const emailEmptyMessage = document.querySelector('.email-empty'); | ||
const emailWrongFormatMessage = document.querySelector('.email-wrong-format'); | ||
|
||
function isCorrectEmailFormat(email) { | ||
const emailRegex = /^[^\s@]+@[^\s@]+\.[^\s@]+$/; | ||
return emailRegex.test(email); | ||
} | ||
Comment on lines
+6
to
+9
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 default function emailValidationCheck(event) { | ||
|
||
if( event.target !== emailInput ) return; | ||
|
||
emailInput.classList.toggle('errored', !emailInput.value || !isCorrectEmailFormat(emailInput.value)); | ||
emailInput.classList.toggle('correct', emailInput.value && isCorrectEmailFormat(emailInput.value)); | ||
|
||
emailEmptyMessage.classList.toggle('hidden', emailInput.value); | ||
emailWrongFormatMessage.classList.toggle('hidden', !emailInput.value || isCorrectEmailFormat(emailInput.value)); | ||
|
||
} |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,11 +1,10 @@ | ||
// 모든 input에 내용이 있는지 체크합니다: 내용이 있다면 (모든 input에 placeholder가 없을 때) true를, 비어있다면 false를 반환합니다. | ||
// 모든 input에 내용이 있는지 체크합니다: 내용이 있다면 true를, 비어있다면 false를 반환합니다. | ||
|
||
const inputs = document.querySelectorAll('input'); | ||
import { inputs } from "./constLib.js"; | ||
|
||
export default function filledInputCheck() { | ||
const hiddenPlaceholders = document.querySelectorAll('input:not(:placeholder-shown)'); | ||
|
||
return hiddenPlaceholders.length === inputs.length | ||
? true | ||
: false; | ||
if (!inputs || !inputs.length) return true; | ||
|
||
return [...inputs].every( (e) => e.value !== '' ); | ||
} |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,14 @@ | ||
import { nicknameInput, btn } from "./constLib.js"; | ||
|
||
const nicknameEmptyMessage = document.querySelector('.nickname-empty'); | ||
|
||
export default function nicknameEmptyCheck(event) { | ||
|
||
if ( !nicknameInput || event.target !== nicknameInput ) return; // 닉네임 란이 없거나 || 닉네임 란에서 발생한 이벤트가 아니라면 return | ||
|
||
nicknameInput.classList.toggle('errored', !nicknameInput.value); | ||
nicknameInput.classList.toggle('correct', nicknameInput.value); | ||
|
||
nicknameEmptyMessage.classList.toggle('hidden', nicknameInput.value); | ||
|
||
} |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,18 @@ | ||
import { passwordInput, btn } from "./constLib.js"; | ||
|
||
const passwordEmptyMessage = document.querySelector('.password-empty'); | ||
const passwordWrongFormatMessage = document.querySelector('.password-wrong-format'); | ||
|
||
const isLongEnough = (str) => str.length >= 8; | ||
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 default function passwordFormatCheck(event) { | ||
|
||
if ( event.target !== passwordInput ) return; | ||
|
||
passwordInput.classList.toggle('errored', !passwordInput.value || !isLongEnough(passwordInput.value)); | ||
passwordInput.classList.toggle('correct', passwordInput.value && isLongEnough(passwordInput.value)); | ||
|
||
passwordEmptyMessage.classList.toggle('hidden', passwordInput.value); | ||
passwordWrongFormatMessage.classList.toggle('hidden', !passwordInput.value || isLongEnough(passwordInput.value)); | ||
|
||
} |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,21 +1,19 @@ | ||
// 회원가입 페이지에서 패스워드와 패스워드 확인 란의 내용이 같은지 체크합니다. | ||
// 같지 않다면 패스워드 확인에 빨간 아웃라인이 나타나고 메시지가 보여집니다. | ||
// 같다면 true를, 같지 않다면 false를 반환합니다. 패스워드 확인 란이 없다면 항상 true를 반환합니다. | ||
// 패스워드 확인 란이 없다면 바로 return 합니다. | ||
|
||
const passwordInput = document.querySelector('#password'); | ||
const verifyPasswordInput = document.querySelector('#verify-password'); | ||
const passwordMismatchingMsg = document.querySelector('.password-mismatching-msg'); | ||
import { passwordInput, verifyPasswordInput } from "./constLib.js"; | ||
|
||
export default function passwordVerifiedCheck() { | ||
if (!verifyPasswordInput) return true; | ||
const passwordMismatchingMessage = document.querySelector('.password-mismatching'); | ||
|
||
if (verifyPasswordInput.value !== passwordInput.value) { | ||
verifyPasswordInput.classList.add('mismatching'); | ||
passwordMismatchingMsg.classList.remove('hidden'); | ||
return false; | ||
} | ||
export default function passwordVerifiedCheck(event) { | ||
if ( !verifyPasswordInput || (event.target !== (verifyPasswordInput || passwordInput)) ) return; // 패스워드 확인 란이 없거나 || 패스워드 또는 패스워드 확인 란에서 발생한 이벤트가 아니라면 return | ||
|
||
verifyPasswordInput.classList.remove('mismatching'); | ||
passwordMismatchingMsg.classList.add('hidden'); | ||
return true; | ||
const isPasswordMatching = passwordInput.value === verifyPasswordInput.value; | ||
const isVerifyPasswordEmpty = verifyPasswordInput.value === ''; | ||
|
||
verifyPasswordInput.classList.toggle('errored', !isPasswordMatching && !isVerifyPasswordEmpty); | ||
verifyPasswordInput.classList.toggle('correct', isPasswordMatching && !isVerifyPasswordEmpty); | ||
|
||
passwordMismatchingMessage.classList.toggle('hidden', isPasswordMatching || isVerifyPasswordEmpty); | ||
} |
This file was deleted.
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,43 @@ | ||
// import된 각 함수들을 이벤트에 지정합니다. | ||
|
||
import toggleVisibility from "./togglePasswordVisibility.js"; | ||
import btnValidCheck from "./buttonValidationCheck.js"; | ||
import { form, btn, loginButtonLink, signupButtonLink } from "./constLib.js"; | ||
import emailValidationCheck from "./emailValidationCheck.js"; | ||
import nicknameEmptyCheck from "./nicknameEmptyCheck.js"; | ||
import passwordVerifiedCheck from "./passwordVerifiedCheck.js"; | ||
import passwordFormatCheck from "./passwordFormatCheck.js"; | ||
import { btnLink } from "./stdLib.js"; | ||
|
||
const passwordVisibilityIcons = document.querySelectorAll('.password-visibility-icon'); | ||
|
||
|
||
// 버튼 disabled 설정 - 페이지 진입 후 아무 동작도 하지 않았을때 버튼이 동작하는걸 방지합니다. | ||
btn.disabled = true; | ||
|
||
|
||
// 버튼 링크 설정 | ||
if (btn.classList.contains('login')) btn.addEventListener('click', () => { btnLink(loginButtonLink) }); | ||
else if (btn.classList.contains('signup')) btn.addEventListener('click', () => { btnLink(signupButtonLink) }); | ||
Comment on lines
+20
to
+21
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. 버튼 관련 로직을 재사용 또는 통일 시키려고 하신 노력이 보이시는것 같네요. 제 생각에는 로직이 다른 파일에 섞이게되면 이게 스노우볼이 되어서 나중에는 관리가 힘들어진다고 생각합니다. 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 btnLink(ref) {
location.href = ref;
}
export { btnLink }
|
||
|
||
|
||
// 눈 이미지에 패스워드 가시성 토글 스크립트 지정 | ||
for (let each of passwordVisibilityIcons) { | ||
each.addEventListener('click', toggleVisibility); | ||
} | ||
|
||
|
||
// 폼에 각 이벤트 지정 | ||
|
||
function eventFunctionsPackage(e) { | ||
|
||
emailValidationCheck(e); | ||
nicknameEmptyCheck(e); | ||
passwordFormatCheck(e); | ||
passwordVerifiedCheck(e); | ||
btnValidCheck(); | ||
|
||
} | ||
|
||
form.addEventListener('focusout', eventFunctionsPackage); | ||
form.addEventListener('input', eventFunctionsPackage); | ||
Comment on lines
+42
to
+43
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. 이 부분이 요구사항과 맞지 않는 부분이 있는 것 같습니다.
실무에서는 재헌님이 하신 방법도 UX를 고려해서 사용하는 방법이긴 합니다만 스프린트 미션에서는 요구사항이 명시되어있어서 우선 그것을 따르는게 맞는것 같아요 ㅎㅎ |
This file was deleted.
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.
여기는 가짜 폼태그보다 진짜 폼태그를 써주는게 어떨까요?