Skip to content

Conversation

@jinsunkimdev
Copy link

요구사항

  • Github에 PR(Pull Request)을 만들어서 미션을 제출합니다.
  • 피그마 디자인에 맞게 페이지를 만들어 주세요.
  • React와 같은 UI 라이브러리를 사용하지 않고 진행합니다.

기본

로그인

  • 이메일 input에서 focus out 할 때, 값이 없을 경우 input에 빨강색 테두리와 아래에 "이메일을 입력해주세요." 빨강색 에러 메세지를 보입니다.
  • 이메일 input에서 focus out 할 때, 이메일 형식에 맞지 않는 경우 input에 빨강색 테두리와 아래에 "잘못된 이메일 형식입니다" 빨강색 에러 메세지를 보입니다.
  • 비밀번호 input에서 focus out 할 때, 값이 없을 경우 아래에 "비밀번호를 입력해주세요." 에러 메세지를 보입니다
  • 비밀번호 input에서 focus out 할 때, 값이 8자 미만일 경우 아래에 "비밀번호를 8자 이상 입력해주세요." 에러 메세지를 보입니다.
  • input 에 빈 값이 있거나 에러 메세지가 있으면 '로그인' 버튼은 비활성화 됩니다.
  • input 에 유효한 값을 입력하면 '로그인' 버튼이 활성화 됩니다.
  • 활성화된 '로그인' 버튼을 누르면 "/items" 로 이동합니다

회원가입

  • 이메일 input에서 focus out 할 때, 값이 없을 경우 input에 빨강색 테두리와 아래에 "이메일을 입력해주세요." 빨강색 에러 메세지를 보입니다.
  • 이메일 input에서 focus out 할 때, 이메일 형식에 맞지 않는 경우 input에 빨강색 테두리와 아래에 "잘못된 이메일 형식입니다" 빨강색 에러 메세지를 보입니다.
  • 닉네임 input에서 focus out 할 때, 값이 없을 경우 input에 빨강색 테두리와 아래에 "닉네임을 입력해주세요." 빨강색 에러 메세지를 보입니다.
  • 비밀번호 input에서 focus out 할 때, 값이 없을 경우 아래에 "비밀번호를 입력해주세요." 에러 메세지를 보입니다
  • 비밀번호 input에서 focus out 할 때, 값이 8자 미만일 경우 아래에 "비밀번호를 8자 이상 입력해주세요." 에러 메세지를 보입니다.
  • 비밀번호 input과 비밀번호 확인 input의 값이 다른 경우, 비밀번호 확인 input 아래에 "비밀번호가 일치하지 않습니다.." 에러 메세지를 보입니다.
  • input 에 빈 값이 있거나 에러 메세지가 있으면 '회원가입' 버튼은 비활성화 됩니다.
  • input 에 유효한 값을 입력하면 '회원가입' 버튼이 활성화 됩니다.
  • 활성화된 '회원가입' 버튼을 누르면 로그인 페이지로 이동합니다

심화

  • 눈 모양 아이콘 클릭시 비밀번호의 문자열이 보이기도 하고, 가려지기도 합니다.
  • 비밀번호의 문자열이 가려질 때는 눈 모양 아이콘에는 사선이 그어져있고, 비밀번호의 문자열이 보일 때는 사선이 없는 눈 모양 아이콘이 보이도록 합니다.

배포

https://starlit-crostata-00fe39.netlify.app/

주요 변경사항

  • 스프린트 미션4 요구사항 반영 완료
  • 스프린트 미션3 코드리뷰 내용 반영
    • index.html<picture>태그 대신에 <img>태그의 srcsetsizes 사용하도록 시도해 보았습니다.(제가 원하는 대로 구현이 잘 되지 않아서 질문란에 질문을 적어놓았습니다.🙇🏻‍♂️
    • 모든 페이지마다 mobile, tablet, desktop 파일이 나눠지는 구조를 페이지마다 css파일을 하나씩만 만들고, 그 안에서 미디어쿼리를 사용해 반응형 레이아웃을 만들어주는 구조로 리팩토링 해봤습니다.
    • 이미지를 사용할때 background-image 속성을 img 태그로 변경해서 코드를 수정했습니다.
    • 컬러코드 네이밍 및 변수 네이밍을 일관성 있도록 수정해 보았습니다.
  • 'input','blur'일 때마다 함수가 실행되면 비효율적일 것 같아서 debounce,이벤트 버블링을 사용해서 최적화를 시도해 보았습니다.
  • 사용하는 함수들을 모듈화 해보았습니다.

스크린샷

로그인

Screenshot 2025-04-29 at 1 19 35 Screenshot 2025-04-29 at 1 20 31

회원가입

Screenshot 2025-04-29 at 1 21 29
Screenshot 2025-04-29 at 1 22 24
Screenshot 2025-04-29 at 1 22 52

멘토에게

  • index.html<picture>태그 대신에 <img>태그의 srcset, sizes만 사용하도록 시도해 보았습니다.
    제가 의도한 것은 화면 크기에 따라 서로 다른 두 이미지를 완전히 교체하는 것이었는데,<img>srcset, sizes를 사용했을 때는 DOM 안의 img src 속성이 교체되지 않고 다운로드되는 리소스만 최적화되는 것을 확인했습니다.
    Property1-2=Typo
    ↓ ↑
    Property 1-2=sm
<!--시도한 코드는 다음과 같습니다.-->
    <img src="/images/Property1-2=sm.png"
        srcset="/images/Property1-2=Typo.png 743w, /images/Property1-2=sm.png 744w"
        sizes="(max-width: 743px) 100vw, 744px" alt="판다마켓 로고" />

저는 srcset, sizes는 같은 이미지의 해상도나 용량을 뷰포트 크기에 맞게 최적화 다운로드하는 기능이고, src 자체를 화면 크기에 따라 교체하려면 <picture> 태그나 JavaScript로 직접 처리해야 한다고 이해하고 있습니다.
혹시 제가 이해한 내용이 정확한지 검토해주시면 감사하겠습니다. 🙇🏻‍♂️

  • index.html에 연결된 index.css 파일을 재사용성과 유지보수를 높이기 위해 변수 중심으로 리팩토링해 보았습니다.
    이렇게 리팩토링하는 방식이 괜찮은지 피드백 부탁드립니다!

  • 스프린트 미션4에 해당하는 자바스크립트 함수들을 제 나름대로 모듈화 및 최적화를 해보았습니다. 좀 더 개선할 방법이 있다면 알려주시면 감사하겠습니다🙇🏻

  • 셀프 코드 리뷰를 통해 질문 이어가겠습니다.

@jinsunkimdev jinsunkimdev added the 매운맛🔥 뒤는 없습니다. 그냥 필터 없이 말해주세요. 책임은 제가 집니다. label Apr 28, 2025
@addiescode-sj addiescode-sj self-requested a review April 30, 2025 08:03
Copy link
Collaborator

@addiescode-sj addiescode-sj left a comment

Choose a reason for hiding this comment

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

수고하셨습니다!
의도를 더 명확히 드러내고 코드를 간소화하려는 시도를 더 해보시면 훨씬 좋을것같네요 👍

주요 리뷰 포인트

  • 유지보수를 고려한 개발
  • debounce 함수 사용 관련 피드백

const input = e.target.closest("[data-validate]");
if (!input) return;
validateInputs(input);
debouncedCheckAll();
Copy link
Collaborator

Choose a reason for hiding this comment

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

이 상황에서는 Debounce를 사용하는 것이 적절하지 않습니다.

이유는:

  • 사용자가 입력한 값에 대한 검증과 피드백은 즉각적인 편이 UX를 생각했을때 좋습니다. 즉, 사용자가 입력한 값에 대한 검증은 올바르지 않은 값인것이 확인되었을때 바로 알려주는것이 좋고, 이 과정에서 불필요한 지연이 발생된다면 오히려 사용자 경험을 저해할 수 있습니다.
  • 현재 validation 로직이 구현되어있는것은 정규표현식을 이용한 매우 가벼운 비교 연산입니다. 따라서 성능 부담이 그다지 크지 않기때문에 쓰로틀링/디바운싱을 적용하는 효용을 비교해봤을때, 오히려 사용자 경험을 저해하게되어 좋지 않습니다.

if (!input) return;
validateInputs(input);
debouncedCheckAll();
});
Copy link
Collaborator

Choose a reason for hiding this comment

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

함수 선언부 블락끼리는 그 사이에 한칸씩 띄워주세요!

// submit
submitBtn.addEventListener("click", (e) => {
e.preventDefault();
if (!submitBtn.disabled) {
Copy link
Collaborator

Choose a reason for hiding this comment

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

굳굳! 예외처리 좋고, redirectMap 객체를 조건문 안에서 선언한것도 괜찮네요 👍
만약 이 객체가 여러 파일에서 재사용될 필요가 있다면 이런식으로 상수화해두고 constants.js와 같은 파일이름으로 모듈화해주는것도 괜찮겠죠?

// constants.js

export const REDIRECT_MAP = {
  "/login.html": "/items.html",
  "/signup.html": "/login.html",
};

Comment on lines +22 to +30
if (passwordInput.type === "password") {
passwordInput.type = "text";
img.src = "/images/btn_visibility_on_24px.png";
img.alt = "비밀번호 보이는 중";
} else {
passwordInput.type = "password";
img.src = "/images/btn_none_visibility_on_24px.png";
img.alt = "비밀번호 숨겨진 상태";
}
Copy link
Collaborator

Choose a reason for hiding this comment

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

if else문을 써서 처리해주는것도 나쁘지않지만, 구조를 생각해봤을때 조건이 여러개 붙는게 아닌 둘중에 하나로 토글되는 방식이니까, 이런 방식을 사용하면 의도가 좀 더 명확히 파악되고 코드도 간결해질수있겠네요 :)

  const isPasswordVisible = passwordInput.type === "password";

  passwordInput.type = isPasswordVisible ? "text" : "password";
  img.src = isPasswordVisible
    ? "/images/btn_visibility_on_24px.png"
    : "/images/btn_none_visibility_on_24px.png";
  img.alt = isPasswordVisible ? "비밀번호 보이는 중" : "비밀번호 숨겨진 상태";

Comment on lines +37 to +38
const { value, id } = inputEl;
if (!validateType || !validators[validateType]) return;
Copy link
Collaborator

Choose a reason for hiding this comment

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

코드 흐름을 좀 더 개선해보려면 38번째라인을 37번째 라인보다 위로 갈 수 있게 순서를 바꾸면 더 좋을것같아요.

if (!validateType || !validators[validateType]) return;
const { isValid, message } = validators[validateType](value);
const errMsg = document.getElementById(`${id}-error`);
if (errMsg) {
Copy link
Collaborator

Choose a reason for hiding this comment

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

40, 41사이에 한칸 띄워주세요 :)

Comment on lines +44 to +48
if (isValid) {
inputEl.classList.remove("input-error");
} else {
inputEl.classList.add("input-error");
}
Copy link
Collaborator

Choose a reason for hiding this comment

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

이 조건문도 classList.toggle을 사용하면 이렇게 간소화할수있답니다!

참고

Suggested change
if (isValid) {
inputEl.classList.remove("input-error");
} else {
inputEl.classList.add("input-error");
}
inputEl.classList.toggle("input-error", !isValid);

Copy link
Collaborator

Choose a reason for hiding this comment

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

굳굳! 유효성 검사 로직은 프로그램내에서 UI와 결합될 필요없이 재사용될 수 있으니, 따로 분리해두고 모듈화하시는게 좋죠 👍

@addiescode-sj
Copy link
Collaborator

addiescode-sj commented Apr 30, 2025

질문에 대한 답변

멘토에게

  • index.html<picture>태그 대신에 <img>태그의 srcset, sizes만 사용하도록 시도해 보았습니다.
    제가 의도한 것은 화면 크기에 따라 서로 다른 두 이미지를 완전히 교체하는 것이었는데,<img>srcset, sizes를 사용했을 때는 DOM 안의 img src 속성이 교체되지 않고 다운로드되는 리소스만 최적화되는 것을 확인했습니다.
    Property1-2=Typo
    ↓ ↑
    Property 1-2=sm
<!--시도한 코드는 다음과 같습니다.-->
    <img src="/images/Property1-2=sm.png"
        srcset="/images/Property1-2=Typo.png 743w, /images/Property1-2=sm.png 744w"
        sizes="(max-width: 743px) 100vw, 744px" alt="판다마켓 로고" />

저는 srcset, sizes는 같은 이미지의 해상도나 용량을 뷰포트 크기에 맞게 최적화 다운로드하는 기능이고, src 자체를 화면 크기에 따라 교체하려면 <picture> 태그나 JavaScript로 직접 처리해야 한다고 이해하고 있습니다. 혹시 제가 이해한 내용이 정확한지 검토해주시면 감사하겠습니다. 🙇🏻‍♂️

  • index.html에 연결된 index.css 파일을 재사용성과 유지보수를 높이기 위해 변수 중심으로 리팩토링해 보았습니다.
    이렇게 리팩토링하는 방식이 괜찮은지 피드백 부탁드립니다!
  • 스프린트 미션4에 해당하는 자바스크립트 함수들을 제 나름대로 모듈화 및 최적화를 해보았습니다. 좀 더 개선할 방법이 있다면 알려주시면 감사하겠습니다🙇🏻
  • 셀프 코드 리뷰를 통해 질문 이어가겠습니다.

네 진선님,이해하신것처럼 src속성은 실제로 변경되지않는게 기본 동작이 맞습니다. srcset과 sizes를 사용하면 가장 적절한 사이즈의 이미지를 골라내 다운로드하는것으로 DOM 속성의 변경은 없지만 내부적으로 다른 사이즈의 이미지를 로드하고 제대로 표시해줍니다.

즉, 반응형에 맞춰서 다른 사이즈의 이미지를 사용한다면 => srcset, sizes 사용
완전히 다른 이미지 소스를 반응형에 따라 보여주고싶다면 => picture 태그를 사용하거나, 자바스크립트를 사용

이렇게 기준을 잡아보시면 좋을 듯 합니다 :)

변수 중심으로 리팩토링 하신 점 아주 좋은 시도입니다! 다만 너무 과도하게 불필요한 값까지 변수화해둬서 좋은건 없으니, 변수화의 기준은 공통적으로 자주 사용되는 값들 위주로 해주시는게 원래 의도에 맞게끔 사용된다는점 참고해보세요 :)

나머지는 본문에서 코멘트로 자세히 피드백 드렸습니다 :)

@addiescode-sj addiescode-sj merged commit 87bf800 into codeit-bootcamp-frontend:Basic-김진선 May 14, 2025
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

매운맛🔥 뒤는 없습니다. 그냥 필터 없이 말해주세요. 책임은 제가 집니다.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants