Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
26 changes: 22 additions & 4 deletions common.css
Original file line number Diff line number Diff line change
Expand Up @@ -122,7 +122,7 @@ html {
}
.footer .menus a {
font-weight: 400;
color: #fff;
color: #e5e7eb;
}
.footer .menus a + a {
margin-left: 30px;
Expand Down Expand Up @@ -151,6 +151,7 @@ html {
padding: 16px 56px 16px 24px;
border-radius: 12px;
background-color: var(--gray100);
border: 1px solid var(--gray100);
box-sizing: border-box;
line-height: 26px;
font-size: 16px;
Expand All @@ -165,18 +166,34 @@ html {
transform: translateY(-50%);
text-indent: -9999px;
}
.input_box.error input {
border-color: #f74747;
}
.error_msg {
display: none;
margin: 8px 16px -6px;
font-weight: 600;
font-size: 14px;
line-height: 24px;
color: #f74747;
}
.input_box.error .error_msg {
display: block;
}

.input_box .btn_pw {
background: url(images/ico_visibility_off.png) no-repeat;
}
.input_box .btn_pw.show {
background: url(images/ico_visibility_on.png) no-repeat;
}
.pc_only {
display: block;
}

.mobile_only {
display: none;
}
.pc_only {
display: block;
}

.tag_text {
margin-bottom: 12px;
Expand Down Expand Up @@ -246,6 +263,7 @@ html {
.input_box .label {
margin-bottom: 8px;
}

.footer {
position: relative;
padding-left: 8%;
Expand Down
110 changes: 105 additions & 5 deletions login.html
Original file line number Diff line number Diff line change
Expand Up @@ -53,6 +53,7 @@ <h1 class="logo large">
id="input_email"
placeholder="이메일을 입력해주세요"
/>
<span class="error_msg"></span>
</div>
<div class="input_box">
<label for="input_pw" class="label">비밀번호</label>
Expand All @@ -62,13 +63,21 @@ <h1 class="logo large">
id="input_pw"
placeholder="비밀번호를 입력해주세요"
/>
<button type="button" class="btn btn_pw">
<span>비밀번호 보이기</span>
</button>
<!--<button type="button" class="btn btn_pw show"><span>비밀번호 보이기</span></button> -->
<div class="btn_pw_show">
<button type="button" class="btn btn_pw">
<span>비밀번호 보이기</span>
</button>
</div>
</div>
<span class="error_msg"></span>
</div>
<button type="submit" class="btn-blue large wide" disabled>
<button
type="type"
class="btn-blue large wide"
id="buttonLogin"
onClick="location.href='./item.html'"
disabled
>
<span>로그인</span>
</button>
<div class="blue_box">
Expand Down Expand Up @@ -100,5 +109,96 @@ <h1 class="logo large">
</form>
</div>
</main>

<script>
const inputs = document.querySelectorAll('input');
const inputEmail = document.querySelector('#input_email');
const inputPw = document.querySelector('#input_pw');
const email_regex = /^[A-Za-z0-9_.\-]+@[A-Za-z0-9\-]+\.[A-Za-z0-9\-]+$/;

inputs.forEach(function (input) {
input.addEventListener('focusout', function () {
inputValidate(input);
toggleLoginButton();
});
});
function inputValidate(input) {
let msg = '';
let inputId = input.getAttribute('id');
if (input.value == '') {
if (inputId == 'input_email') msg = '이메일을 입력해주세요.';
else if (inputId == 'input_pw' || inputId == 'input_pw_check')
msg = '비밀번호를 입력해주세요.';
} else {
if (inputId == 'input_email') {
if (email_regex.test(inputEmail.value) == false)
msg = '잘못된 이메일 형식입니다.';
} else {
msg = '';
}

if (inputId == 'input_pw') {
const pw = inputPw.value;
if (inputId === 'input_pw' && pw.length < 8) {
msg = '비밀번호를 8자 이상 입력해주세요.';
} else {
msg = '';
}
}
}

setInputBlurMessage(input, msg);
}
function setInputBlurMessage(input, msg) {
let inputBox = input.closest('.input_box');
let errorMsg = inputBox.querySelector('.error_msg');
inputBox.classList.remove('error');
errorMsg.innerText = '';
if (msg) {
inputBox.classList.add('error');
errorMsg.innerText = msg;
}
}

function toggleLoginButton() {
const buttonLogin = document.querySelector('#buttonLogin');
const inputs = document.querySelectorAll('input');
const errors = document.querySelectorAll('.error_msg');

const emptyInputs = Array.from(inputs).filter(
(input) => input.value.trim() === ''
);

const errorMessages = Array.from(errors).filter(
(error) => error.innerText.trim() !== ''
);

if (emptyInputs.length === 0 && errorMessages.length === 0) {
buttonLogin.removeAttribute('disabled');
} else {
buttonLogin.setAttribute('disabled', 'disabled');
}
}
const toggleButtons = document.querySelectorAll('.btn_pw');

toggleButtons.forEach(function (button) {
button.addEventListener('click', function () {
const inputWrapper = button.closest('.input');
const input = inputWrapper.querySelector('input');
const span = button.querySelector('span');

if (input.value == '') return;
if (input.type === 'password') {
button.classList.add('show');
input.type = 'text';
span.innerText = '비밀번호 숨기기';
} else {
button.classList.remove('show');
input.type = 'password';
span.innerText = '비밀번호 보이기';
}
});
});
</script>
</body>
</html>
164 changes: 142 additions & 22 deletions signup.html
Original file line number Diff line number Diff line change
Expand Up @@ -53,6 +53,7 @@ <h1 class="logo large">
id="input_email"
placeholder="이메일을 입력해주세요"
/>
<span class="error_msg"></span>
</div>
<div class="input_box">
<label for="input_nickname" class="label">닉네임</label>
Expand All @@ -61,36 +62,51 @@ <h1 class="logo large">
id="input_nickname"
placeholder="닉네임을 입력해주세요"
/>
<span class="error_msg"></span>
</div>
<div class="input_box">
<label for="input_pw" class="label">비밀번호</label>
<div class="input btn_group">
<input
type="password"
id="input_pw"
placeholder="비밀번호를 입력해주세요"
/>
<button type="button" class="btn btn_pw">
<span>비밀번호 보이기</span>
</button>
<!--<button type="button" class="btn btn_pw show"><span>비밀번호 보이기</span></button> -->
<div class="btn_group">
<div class="input">
<input
type="password"
id="input_pw"
placeholder="비밀번호를 입력해주세요"
/>
<div class="btn_pw_show">
<button type="button" class="btn btn_pw">
<span>비밀번호 보이기</span>
</button>
</div>
</div>
<span class="error_msg"></span>
</div>
</div>
<div class="input_box">
<label for="input_pw" class="label">비밀번호 확인</label>
<div class="input btn_group">
<input
type="password"
id="input_pw"
placeholder="비밀번호를 다시 한 번 입력해주세요"
/>
<button type="button" class="btn btn_pw">
<span>비밀번호 보이기</span>
</button>
<!--<button type="button" class="btn btn_pw show"><span>비밀번호 보이기</span></button> -->
<label for="input_pw_check" class="label">비밀번호 확인</label>
<div class="btn_group">
<div class="input">
<input
type="password"
id="input_pw_check"
placeholder="비밀번호를 다시 한 번 입력해주세요"
/>
<div class="btn_pw_show">
<button type="button" class="btn btn_pw">
<span>비밀번호 보이기</span>
</button>
</div>
</div>
<span class="error_msg"></span>
</div>
</div>
<button type="submit" class="btn-blue large wide" disabled>
<button
type="button"
class="btn-blue large wide"
id="buttonJoin"
onClick="location.href='./login.html'"
disabled
>
<span>회원가입</span>
</button>
<div class="blue_box">
Expand Down Expand Up @@ -122,5 +138,109 @@ <h1 class="logo large">
</form>
</div>
</main>

<script>
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

스크립트 파일을 따로 만드시면 좀 더 깔끔하게 정리할 수 있습니다 :)
그리고 로그인, 회원가입 페이지에 겹치는 부분이 많은데, module 로 만드시면 공통된 부분을 import해서 쓸 수 있죠!

https://developer.mozilla.org/ko/docs/Web/JavaScript/Guide/Modules#applying_the_module_to_your_html

const inputs = document.querySelectorAll('input');
const inputEmail = document.querySelector('#input_email');
const inputPw = document.querySelector('#input_pw');
const inputPwCheck = document.querySelector('#input_pw_check');
const email_regex = /^[A-Za-z0-9_.\-]+@[A-Za-z0-9\-]+\.[A-Za-z0-9\-]+$/;
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

정규식을 써주셨군요! 👍


inputs.forEach(function (input) {
input.addEventListener('focusout', function () {
inputValidate(input);
if (input.id === 'input_pw') inputValidate(inputPwCheck);
if (input.id === 'input_pw_check') inputValidate(inputPw);
toggleJoinButton();
});
});
function inputValidate(input) {
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

기능이 여러개 있는데, 전체적으로 어떤 구조로 짜야하는지 어려웠습니다.
인풋 여러개를 너무 여러가지 조건을 나눠서 구분하고 있는 것 같기도 하고,
깔끔하지 않다는 느낌이 드는데, 왜 그런지 알 수 있으면 좋을 것 같습니다

-> 지금은 하나의 함수가 너무 많은 일을 하고 있어요!
우선 전반적으로 로직을 작게 자르고 함수로 정의해 보시면 좋을 거 같습니다.

예를 들면

 function validateEmail(value) {
    if (!value) {
      return "이메일을 입력해주세요.";
    } else if (email_regex.test(value) == false) {
      return "잘못된 이메일 형식입니다.";
    }
    return "";
  }

이렇게 인풋 단위로만 쪼개도 코드 파악 하기가 훨씬 쉬워집니다.

function inputValidate(input) {
    let msg = "";
    let inputId = input.getAttribute("id");

    if (inputId == "input_email") {
      msg = validateEmail(input.value);
    } else if (inputId == "input_nickname") {
      msg = validateNickname(input.value);
    } 
    // ...

    setInputBlurMessage(input, msg);
 }

더 나아가 여기서 함수의 역할을 더 명확하게 하기 위해 유효성 검사를 제외한 부분은 제거할 수도 있겠죠!

function inputValidate(input) {
    let msg = "";
    let inputId = input.getAttribute("id");
    if (inputId == "input_email") {
      msg = validateEmail(input.value);
    } else if (inputId == "input_nickname") {
      msg = validateNickname(input.value);
    } 
   
    // ...
   return msg;
}

 function handleBlurInput(e) {
      const input = e.target;
      const errorMessage = inputValidate(input);
      if (errorMessage) {
        setInputBlurMessage(input, errorMessage);
      }
    } 

inputs.forEach(function (input) {
    input.addEventListener("focusout", handleBlurInput);
 });

이렇게 함수의 역할을 줄이고 (가능하면 하나의 책임만) 이름만 잘 지어줘도 코드 읽기가 훨씬 쉽습니다!

현재 inputValidate는 if문을 해석하며 파악해야 하지만 위처럼 함수로 묶어주면 이메일을 검증하고 있구나~ 닉네임을 검증하는구나~ 하고 바로 알 수 있죠!

결국 우리가 코드를 잘 짜도록 노력하는 이유는 유지 보수하기 쉽도록 하는 것이죠. 원하는 코드를 쉽게 찾고, 쉽게 수정 가능해야 합니다. 그런데 하나의 함수에 너무 많은 일을 하면 코드를 파악하기 힘들고, 로직간에 서로 영향을 받을 가능성이 커집니다!

let msg = '';
let inputId = input.getAttribute('id');
if (input.value == '') {
if (inputId == 'input_email') msg = '이메일을 입력해주세요.';
if (inputId == 'input_nickname') msg = '닉네임을 입력해주세요.';
else if (inputId == 'input_pw' || inputId == 'input_pw_check')
msg = '비밀번호를 입력해주세요.';
} else {
if (inputId == 'input_email') {
if (email_regex.test(inputEmail.value) == false)
msg = '잘못된 이메일 형식입니다.';
} else {
msg = '';
}

if (inputId == 'input_pw' || inputId == 'input_pw_check') {
const pw = inputPw.value;
const pwCheck = inputPwCheck.value;
if (inputId === 'input_pw' && pw.length < 8) {
msg = '비밀번호를 8자 이상 입력해주세요.';
} else if (inputId === 'input_pw_check' && pwCheck.length < 8) {
msg = '비밀번호를 8자 이상 입력해주세요.';
} else if (pw !== '' && pwCheck !== '' && pw !== pwCheck) {
msg = '비밀번호가 일치하지 않습니다.';
} else {
msg = '';
}
}

if (inputId == 'input_nickname') {
msg = '';
}
}

setInputBlurMessage(input, msg);
}
function setInputBlurMessage(input, msg) {
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

함수명을 좀 더 명확하게 해주면 좋을 거 같습니다! 이 함수의 목적은 무엇인가요?
에러 UI를 다루는 것이라면 handeErrorUI 같은 이름이 좀 더 직관적일 거 같습니다!

let inputBox = input.closest('.input_box');
let errorMsg = inputBox.querySelector('.error_msg');
inputBox.classList.remove('error');
errorMsg.innerText = '';
if (msg) {
inputBox.classList.add('error');
errorMsg.innerText = msg;
}
}

function toggleJoinButton() {
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

여기도 마찬가지입니다! 어떤 것을 토글하는 것인가요?
버튼의 disabled 상태를 관리하는 것이라면
updateSubmitButtonState 정도가 있겠네요!

const buttonJoin = document.querySelector('#buttonJoin');
const inputs = document.querySelectorAll('input');
const errors = document.querySelectorAll('.error_msg');

const emptyInputs = Array.from(inputs).filter(
(input) => input.value.trim() === ''
);

const errorMessages = Array.from(errors).filter(
(error) => error.innerText.trim() !== ''
);

if (emptyInputs.length === 0 && errorMessages.length === 0) {
buttonJoin.removeAttribute('disabled');
} else {
buttonJoin.setAttribute('disabled', 'disabled');
}
}
const toggleButtons = document.querySelectorAll('.btn_pw');

toggleButtons.forEach(function (button) {
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

이 부분도 함수로 묶어 주기만 해도 훨씬 파악하기 쉽죠!

toggleButtons.forEach(function (button) {
     button.addEventListener('click', togglePasswordVisibility)
  }
}

button.addEventListener('click', function () {
const inputWrapper = button.closest('.input');
const input = inputWrapper.querySelector('input');
const span = button.querySelector('span');

if (input.value == '') return;
if (input.type === 'password') {
button.classList.add('show');
input.type = 'text';
span.innerText = '비밀번호 숨기기';
} else {
button.classList.remove('show');
input.type = 'password';
span.innerText = '비밀번호 보이기';
}
});
});
</script>
</body>
</html>
Loading