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
9 changes: 6 additions & 3 deletions login.html
Original file line number Diff line number Diff line change
Expand Up @@ -12,13 +12,15 @@
</header>
<main>
<label for="email" class="labels">이메일</label>
<input id="email" type="email" name="useremail" class="inputbox"placeholder="이메일을 입력해 주세요.">
<input id="email" type="email" name="useremail" class="inputbox" placeholder="이메일을 입력해 주세요.">
<div id="emailError" class = "errormsg"></div>
<label for="password" class="labels" >비밀번호</label>
<div class="passwordbox">
<input id="password" type="password" name="password" class="inputbox" placeholder="비밀번호를 입력해 주세요.">
<span class="blindIco"><img src="/img/password_on.svg" alt="blinder"></span>
<span class="blindIco" id="pwtoggle"><img src="/img/password_on.svg" alt="blinder" id="pwOn"><img src="/img/password_off.svg" alt="blinder" id="pwOff"></span>
</div>
<button type="submit">로그인</button>
<div id="passwordError" class = "errormsg"></div>
<button onclick=location.href='/items.html' id = "btn" class="disabled">로그인</button>
<div class="simple">
<span>간편 로그인하기</span>
<span>
Expand All @@ -30,5 +32,6 @@
판다마켓이 처음이신가요?<a href="/signup.html">회원가입</a>
</div>
</main>
<script src="login.js"></script>
</body>
</html>
82 changes: 82 additions & 0 deletions login.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,82 @@
const emailInput = document.getElementById("email");
const passwordInput = document.getElementById("password");
const emailError = document.getElementById("emailError");
const passwordError = document.getElementById("passwordError");

const button = document.getElementById("btn");
const pwtoggle = document.getElementById("pwtoggle");
const pwon = document.getElementById("pwOn");
const pwoff = document.getElementById("pwOff")



const emailPattern = /^[^\s@]+@[^\s@]+\.[^\s@]+$/;
const error={
email : 0,
password : 0,
};

emailInput.addEventListener("focusout",function() {
const value = emailInput.value.trim();
if (value==""){
emailError.textContent = "이메일을 입력해 주세요";
emailError.style.display = "block";
emailInput.classList.add("errorborder");
error.email =0;
}else if(!emailPattern.test(value)){
Comment on lines +21 to +26
Copy link
Collaborator

Choose a reason for hiding this comment

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

혹시 아직 프리티어를 적용하지 않으셨나요 ?

Suggested change
if (value==""){
emailError.textContent = "이메일을 입력해 주세요";
emailError.style.display = "block";
emailInput.classList.add("errorborder");
error.email =0;
}else if(!emailPattern.test(value)){
if (value=="") {
emailError.textContent = "이메일을 입력해 주세요";
emailError.style.display = "block";
emailInput.classList.add("errorborder");
error.email = 0;
} else if(!emailPattern.test(value)) {

사소한 줄바꿈, 띄어쓰기 등 코드를 작성하시다보면 자연스럽게 불규칙해지는 경우가 많아요.
이를 돕기 위해서 개발 커뮤니티에서는 개발 경험 향상을 위한 여러가지 도구들이 있는데요.

보편적으로 많이 사용되는 툴은 prettier입니다 !

Prettier: https://prettier.io/

prettier는 vscode plugin에서 install하고 실행할 수 있습니다 ! 🤗

macos 경우 option + shift + f
windows의 경우 alt + shift + f

emailError.textContent = "잘못된 이메일 형식입니다.";
emailError.style.display = "block";
emailInput.classList.add("errorborder");
Copy link
Collaborator

Choose a reason for hiding this comment

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

클래스 이름에 띄어쓰기가 명확하지 않은 것 같군요 ..!

Suggested change
emailInput.classList.add("errorborder");
emailInput.classList.add("error-border");

네이밍 컨벤션을 한 번 살펴보면 좋을 것 같아요 ! 😉

네이밍 컨벤션

error.email =0;
}else{
emailError.style.display="none"
emailInput.classList.remove("errorborder");
error.email =1;
Copy link
Collaborator

Choose a reason for hiding this comment

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

에러가 존재한다면 1 아니라면 0일까요?

Suggested change
error.email =1;
error.email = true;

만약 그렇다면 Number 타입보다 Boolean 타입을 사용하는 것이 메모리 측면과 코드 의사 측면에서 더 유리할 것으로 사료됩니다 😇

}
updateButtonState()
})

passwordInput.addEventListener("focusout", function(){
const value = passwordInput.value;
if(value == ""){
passwordError.textContent = "비밀번호를 입력해 주세요";
passwordError.style.display = "block";
passwordInput.classList.add("errorborder");
error.password=0;
}else if(value.length<8){
passwordError.textContent = "비밀번호를 8자 이상 입력해 주세요";
passwordError.style.display = "block";
passwordInput.classList.add("errorborder");
error.password=0;
}else{
passwordError.style.display="none"
error.password = 1;
passwordInput.classList.remove("errorborder");
error.password=1;
}
updateButtonState()
});

let showPw = false;

pwtoggle.addEventListener('click', function() {
showPw = !showPw;
passwordInput.type = showPw ? 'text' : 'password';

pwon.style.display = showPw ? 'none' : 'inline';
pwoff.style.display = showPw ? 'inline' : 'none';
});

function updateButtonState(){
const validcheck = error.email * error.password;
Copy link
Collaborator

Choose a reason for hiding this comment

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

오잉? 혹시 곱하기가 "두 조건이 참일 경우"를 의미하는걸까요?

만약 boolean으로 바뀐다면 다음과 같이 바꿀 수 있겠네요 !:

Suggested change
const validcheck = error.email * error.password;
const validcheck = error.email && error.password;

Copy link
Collaborator

Choose a reason for hiding this comment

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

또한 해당 변수도 마찬가지로 네이밍 컨벤션을 따르는게 좋을 것 같아요 !

Suggested change
const validcheck = error.email * error.password;
const validCheck = error.email && error.password;

그리고 만약 boolean일 경우 is-, has-와 같이 의문으로 짓는 경우가 많습니다 !
정훈님과 같은 경우 isValidFormData와 같이 될 수 있겠네요 😉

일반적인 네이밍 컨벤션 보기

if(validcheck ==1){
button.disabled = false;
button.classList.remove("disabled");
button.classList.add("enabled");
}else {
button.disabled = true;
button.classList.add("disabled");
button.classList.remove("enabled");
}
}

25 changes: 22 additions & 3 deletions loginstyle.css
Original file line number Diff line number Diff line change
Expand Up @@ -57,6 +57,9 @@ main{
line-height: 26px;
font-style: regular;
}
.errorborder{
border :2px solid #f74747;
}
.labels{
text-align: left;
font-size: 18px;
Expand All @@ -65,14 +68,13 @@ main{
font-style: bold;
color: var(--gray800);
}
button{
#btn{
margin:16px 0;
padding : 16px 124px;
gap : 10px;
height : 56px;
border-radius: 40px;
color: var(--gray100);
background-color: var(--gray400);
color: var(--gray100);
width : 100%;
font-size: 20px;
font-weight: 600;
Expand All @@ -82,6 +84,13 @@ button{
justify-content: center;
align-items: center;
}
.disabled{
background-color: var(--gray400);
}
.enabled{
background-color: var(--blue);
}

.simple{
display: flex;
justify-content: space-between;
Expand Down Expand Up @@ -115,6 +124,16 @@ button{
right : 17px;
top : 17px;
}
#pwOff,
#pcOff{
display : none;
}
.errormsg{
font-size: 14px;
font-weight : 600;
color:#f74747;
margin-left: 20px;
}
/*태블릿*/
@media(min-width : 768px) and (max-width : 1199px){

Expand Down
19 changes: 12 additions & 7 deletions signup.html
Original file line number Diff line number Diff line change
Expand Up @@ -11,19 +11,23 @@
<main>
<label for="email" class="labels">이메일</label>
<input id="email" type="email" name="useremail" class="inputbox" placeholder="이메일을 입력해 주세요.">
<div id="emailError" class = "errormsg"></div>
<label for="nickname" class="labels">닉네임</label>
<input id="nickname" name="username" class="inputbox" placeholder="닉네임을 입력해 주세요.">
<input id="nickname" name="username" class="inputbox" placeholder="닉네임을 입력해 주세요.">
<div id="nicknameError" class = "errormsg"></div>
<label for="password" class="labels" >비밀번호</label>
<div class="passwordbox">
<input id="password" type="password" name="password" class="inputbox" placeholder="비밀번호를 입력해 주세요.">
<span class="blindIco"><img src="/img/password_on.svg" alt="blinder"></span>
</div>
<span class="blindIco" id="pwtoggle" ><img src="/img/password_on.svg" alt="blinder" id="pwOn"><img src="/img/password_off.svg" alt="blinder" id="pwOff"></span>
</div>
<div id="passwordError" class = "errormsg"></div>
<label for="passwordcheck" class="labels" >비밀번호 확인</label>
<div class="passwordbox">
<input id="passwordcheck" type="password" name="password" class="inputbox" placeholder="비밀번호를를 다시 한 번 입력해 주세요.">
<span class="blindIco"><img src="/img/password_off.svg" alt="blinder"></span>
</div>
<button type="submit">회원가입</button>
<input id="passwordcheck" type="password" name="password" class="inputbox" placeholder="비밀번호를 다시 한 번 입력해 주세요.">
<span class="blindIco" id="pctoggle"><img src="/img/password_on.svg" alt="blinder" id="pcOn"><img src="/img/password_off.svg" alt="blinder" id="pcOff"></span>
</div>
<div id="passwordcheckError" class = "errormsg"></div>
<button onclick=location.href='/login.html' id="btn" class="disabled">회원가입</button>
<div class="simple">
<span>간편 로그인하기</span>
<span>
Expand All @@ -35,5 +39,6 @@
판다마켓이 처음이신가요?<a href="/login.html">로그인</a>
</div>
</main>
<script src="signup.js"></script>
</body>
</html>
135 changes: 135 additions & 0 deletions signup.js
Copy link
Collaborator

Choose a reason for hiding this comment

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

(심화/생각해보기) signup.jslogin.js... 중복된 로직이 있으면 점점 복잡해질 수 있습니다 ~! 😊

여러 페이지에서 비슷한 기능을 하는 코드들이 반복되고 있다면?

로그인, 회원가입 등 페이지마다 공통적인 유효성 검사나 동작이 존재하는 경우가 많습니다.
이러한 로직을 각 JS 파일에 그때그때 작성하게 되면 아래와 같은 문제가 생길 수 있어요:

  • 로직 수정 시, 모든 파일을 수정해야 해요.
  • 서로 약간씩 다른 방식으로 유사한 로직을 구현하게 되면 버그 발생 가능성이 증가합니다.
  • 공통 로직의 변화가 전체 페이지에 ripple effect(연쇄 영향)를 줄 수 있어요.

이처럼 중복된 코드가 많아질수록, 전체 프로젝트의 유지보수 비용은 계속 높아지게 됩니다.

그렇다면 어떻게 할까?

그렇다면 어떻게 할 수 있을까요?

재사용이 필요한 로직은 별도 모듈로 분리해서 관리하고,
각 페이지는 해당 모듈을 가져와 사용하는 방식으로 구성해보는 건 어떨까요?

// validate.js
export function isValidEmail(email) { ... }
export function isValidPassword(password) { ... }
// sign-in.js
import { isValidEmail } from './validate.js';

Copy link
Collaborator

Choose a reason for hiding this comment

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

그럼 언제 분리 해야하는거지?

사실 이건 “경험”으로 익혀가는 부분이지만, 아래와 같은 신호가 있다면 분리를 고려해볼 수 있어요:

  • "어? 이 함수 다른 데서도 쓸 것 같은데?"
  • "이거 수정하려면 다른 JS 파일에도 가서 고쳐야 하네?"
  • "이 기능이 특정 페이지에만 종속되지 않아!"
    어떻게 하면 더 나은 설계를 할 수 있을까?”를 고민하는 건 아주 중요한 개발자의 태도예요.
    정답은 없지만, 재사용성과 유지보수성이라는 기준을 계속 떠올리면서 코드를 분리하는 연습을 하다 보면,
    더욱 확장성 있는 구조를 만들 수 있게 됩니다.

Original file line number Diff line number Diff line change
@@ -0,0 +1,135 @@
const emailInput =document.getElementById("email");
const nicknameInput = document.getElementById("nickname");
const passwordInput = document.getElementById("password");
const passwordcheckInput = document.getElementById("passwordcheck");

const emailError =document.getElementById("emailError");
const nicknameError = document.getElementById("nicknameError");
const passwordError = document.getElementById("passwordError");
const passwordcheckError = document.getElementById("passwordcheckError");
const pwtoggle = document.getElementById("pwtoggle");
const pwon = document.getElementById("pwOn");
const pwoff = document.getElementById("pwOff")
const pctoggle = document.getElementById("pctoggle");
const pcon = document.getElementById("pcOn");
const pcoff = document.getElementById("pcOff")

const button = document.getElementById("btn");



const emailPattern = /^[^\s@]+@[^\s@]+\.[^\s@]+$/;
const error={
email : 0,
nickname : 0,
password : 0,
passwordcheck : 0,
};
emailInput.addEventListener("focusout",function() {
const value = emailInput.value.trim();
if (value==""){
emailError.textContent = "이메일을 입력해 주세요";
emailError.style.display = "block";
emailInput.classList.add("errorborder");
error.email =0;
}else if(!emailPattern.test(value)){
emailError.textContent = "잘못된 이메일 형식입니다.";
emailError.style.display = "block";
emailInput.classList.add("errorborder");
error.email =0;
}else{
emailError.style.display="none"
emailInput.classList.remove("errorborder");
error.email =1;
}
updateButtonState()
})

nicknameInput.addEventListener("focusout",function(){
const value = nicknameInput.value;
if(value == ""){
nicknameError.textContent = "닉네임을 입력해 주세요";
nicknameError.style.display = "block";
nicknameInput.classList.add("errorborder");
error.nickname =0;
}else{
nicknameError.style.display = "none"
nicknameInput.classList.remove("errorborder");
error.nickname =1;
}
updateButtonState()
})

passwordInput.addEventListener("focusout", function(){
const value = passwordInput.value;
if(value == ""){
passwordError.textContent = "비밀번호를 입력해 주세요";
passwordError.style.display = "block";
passwordInput.classList.add("errorborder");
error.password =0;
}else if(value.length<8){
passwordError.textContent = "비밀번호를 8자 이상 입력해 주세요";
passwordError.style.display = "block";
passwordInput.classList.add("errorborder");
error.password =0;
}else{
passwordError.style.display="none"
passwordInput.classList.remove("errorborder");
error.password =1;
}
updateButtonState()
})

passwordcheckInput.addEventListener("focusout",function(){
const value = passwordcheckInput.value;
const pw = passwordInput.value;
if(value.length<8){
passwordcheckError.textContent = "비밀번호를 8자 이상 입력해 주세요";
passwordcheckError.style.display = "block";
passwordcheckInput.classList.add("errorborder");
error.passwordcheck =0;
}else if(value != pw){
passwordcheckError.textContent = "비밀번호가 일치하지 않습니다.";
passwordcheckError.style.display = "block";
passwordcheckInput.classList.add("errorborder");
error.passwordcheck =0;
}else{
passwordcheckError.style.display="none"
passwordcheckInput.classList.remove("errorborder");
error.passwordcheck =1;
}
updateButtonState()
})

let showPw = false;
let showPc = false;

pwtoggle.addEventListener('click', function() {
showPw = !showPw;
passwordInput.type = showPw ? 'text' : 'password';

pwon.style.display = showPw ? 'none' : 'inline';
pwoff.style.display = showPw ? 'inline' : 'none';
});

pctoggle.addEventListener('click', function() {
showPc = !showPc;
passwordcheckInput.type = showPc ? 'text' : 'password';

pcon.style.display = showPc ? 'none' : 'inline';
pcoff.style.display = showPc ? 'inline' : 'none';
});

function updateButtonState(){
const validcheck = error.email * error.password * error.nickname * error.passwordcheck;
if(validcheck ==1){
button.disabled = false;
button.classList.remove("disabled");
button.classList.add("enabled");
}else {
button.disabled = true;
button.classList.add("disabled");
button.classList.remove("enabled");
}
}

14 changes: 7 additions & 7 deletions style.css
Original file line number Diff line number Diff line change
Expand Up @@ -324,18 +324,18 @@ footer{
}
.img{
width : 100%;
max-height: 260px;
overflow: hidden;
max-height : 260px;
overflow : hidden;
}
footer{
flex-wrap: wrap;
justify-content: space-between;
flex-wrap : wrap;
justify-content : space-between;
padding : 32px;
height:160px;
height : 160px;
}
#links>*{
margin-left: 0;
margin-right: 32px;
margin-left : 0;
margin-right : 32px;
}
#bn{
order:3;
Expand Down
Loading