본문 바로가기
D.evelop/Projects

[clone project]Danstagram - js (Login page)

by Danne 2021. 9. 12.

첫 클론 프로젝트  Danstagram★ 

 

[로그인 페이지 - 필수 구현 사항] id, pw에 각각 한글자 이상 입력되어야 버튼이 활성화 되도록 하기.

 

 

✔️ 첫 번째 버전 ( Refactoring 전) - 소요시간 약 1h

const isId = document.getElementById('user_id');
const isPw = document.getElementById('user_pw');
const letsLogin = document.getElementById('btn_login');

// id에 키업 때 한 글자 이상 있는지 체크
// pw에 키업 때 한 글자 이상 있는지 체크
// 두 다 글자 있는지 체크
// 둘 다 한 글자 이상 있으면 login버튼 active
// 둘 중 하나 비었으면 있으면 login버튼 active XXX

isId.addEventListener('keyup',()=>{

    let isIdvalue = isId.value.length;
    let isPwValue = isPw.value.length;
 
    if (0 < isIdvalue && 0 < isPwValue){
        letsLogin.classList.add('active');
    } else {
        letsLogin.classList.remove('active');
    }
})


isPw.addEventListener('keyup',()=>{

    let isIdvalue = isId.value.length;
    let isPwValue = isPw.value.length;
 
    if (0 < isIdvalue && 0 < isPwValue){
        letsLogin.classList.add('active');
    } else {
        letsLogin.classList.remove('active');
    }
})

우선 javascript는 id로 해결해보고 싶어서 id값만 사용했다.

css로의 '스타일 작업'과 js로의 '기능 부여 작업'간의 충돌을 줄일 수 있지 않을까?하는 생각으로

처음엔 어떤 변수와 어떤 함수가 필요할 지 하나하나 분리해 주석으로 적어두고 하나하나 해결하는 방향으로 진행했다.

  • 먼저 id/pw의 input으로 받아오는 value의 length를 각각 구한다.
  • 그리고 그 값이 모두 0보다 크다면, 미리 스타일을 지정해둔 active 클래스를 추가한다.
  • 그리고 두 값 중 하나가 0보다 작거나 같으면 active 클래스를 제거한다.
.login_wrap button{
    height: 40px;
    margin: 23px 0;
    color: #fff;
    background: #c4e1fb;
    border-radius: 5px;
    font-size: 1.2em;
    line-height: 1;
    text-align: center;
    transition: all 0.3s;
    cursor: default;
}

.login_wrap button.active{
    background: #52adff;
    cursor: pointer;
}

 

 

 

✔️ 두 번째 버전 ( Refactoring 진행) - 소요시간 약 30h

const isId = document.getElementById('user_id');
const isPw = document.getElementById('user_pw');
const letsLogin = document.getElementById('btn_login');

isId.addEventListener('keyup',activeBtn)
isPw.addEventListener('keyup',activeBtn)

function activeBtn(){

    let isIdvalue = isId.value.length;
    let isPwValue = isPw.value.length;
 
    if (0 < isIdvalue && 0 < isPwValue){
        letsLogin.classList.add('active');
    } else {
        letsLogin.classList.remove('active');
    }
}

id와 pw 각각의 이벤트에 똑같은 함수를 적은 게 비효율 적인 것 같아. 하나로 줄여보았다.

  • 더 간략하게 적을 수 있을 것 같았다.
  • letsLogin이라는 이름이 마음에 들지 않는데, 좋은 이름이 생각나지 않는다.

 

✔️ 세 번째 버전 (Wrap Up세션 후,  Refactoring 추가 진행) - 소요시간 약 3h

TIP : 각각의 기능을 적당한 단위로 나눠서 생각하기

"use strict";

const loginForm = document.getElementById('loginForm');
const btnLogin = document.getElementById('btnLogin');

// id 조건 체크
function checkId(value){
  return (value.length > 0 ? true : false);
}

// pw 조건 체크
function checkPw(value){
  return (value.length > 0 ? true : false);
}

// id 조건 && pw 조건이 모두 일치하는 지 체크
function checkAllInput(){
  const valueId = document.getElementById('userId').value;
  const valuePw = document.getElementById('userPw').value;

  const isValueId = checkId(valueId);
  const isvaluePw = checkPw(valuePw);
 
  if (isValueId && isvaluePw) {
    Login(true);
  } else {
    Login(false);
  }
}

// id 조건 && pw 조건에 따른 스타일 클래스 추가, 제거
function Login(checkAllInput){
  const btnStyle = btnLogin.classList;
  checkAllInput ? btnStyle.add('active') : btnStyle.remove('active');
  btnLogin.disalbed = !checkAllInput;
}

const init = () => {
  loginForm.addEventListener('input',checkAllInput)
};

init();
  • 최대한 줄이고 싶어 if문을 삼항연산자로 쭉 적었다가, '또 다른 조건'이 있을 만한 함수는 다시 if문으로 바꿨다.
  • 변수를 얼만큼 생성하는게 적당한지 감이 안와서 최대한 많이 작성했다가, 최대한 줄였다가를 반복해봤다.
    '너무 길어진다 싶을 때' 변수로 생성했다. 적당선을 찾는 건 일단 많이 사용해봐야 감이 잡힐 것 같다.
// 예 )
function checkAllInput(){
  const isValueId = checkId(document.getElementById('userId').value;);
  const isvaluePw = checkPw(document.getElementById('userPw').value;);
  // 이렇게 작성하니 너무 길어 가독성이 떨어지느 것 같아 변수에 담아 작성하기로 했다.
 
  if (isValueId && isvaluePw) {
    Login(true);
  } else {
    Login(false);
  }
}

 

 

✏️한 줄 한 줄 의미 달아보기

"use strict";
/* 
 - strict : 엄격한
 - JS의 기본 값은 "sloop mode(느슨한 모드)
 - "보안"적인 측명이 중요할 때 사용 (일반적으로 React에서는 자동 적용되있음)
 - 프로퍼티 정의, 올바르게 선언되지 않은 변수 등 javascript가 알아서 해결해줬던 문제들을 봐주지 않음.
 */

const loginForm = document.getElementById('loginForm');
const btnLogin = document.getElementById('btnLogin');

// id 조건 체크
function checkId(value){
  return (value.length > 0 ? true : false);
}

// pw 조건 체크
function checkPw(value){
  return (value.length > 0 ? true : false);
}
/*
- 추후에 id와 pw의 조건이 추가 될 수 있으므로 두 개를 함수를 분히해서 작성함.
- 확장성을 고려한 것!
*/


// id 조건 && pw 조건이 모두 일치하는지 체크
function checkAllInput(){
  const valueId = document.getElementById('userId').value;
  const valuePw = document.getElementById('userPw').value;

  const isValueId = checkId(valueId);
  const isvaluePw = checkPw(valuePw);
 
  if (isValueId && isvaluePw) {
    Login(true);
  } else {
    Login(false);
  }
}

// id 조건 && pw 조건에 따른 스타일 클래스 추가, 제거
function Login(checkAllInput){
  const btnStyle = btnLogin.classList;
  checkAllInput ? btnStyle.add('active') : btnStyle.remove('active');
  // checkAllInput이 true이면 active클래스 추가 : false이면 제거 
  btnLogin.disalbed = !checkAllInput;
  // disabled : 버튼을 비활성화 하는 속성
  // btnLogin.disalbed = checkAllInput ? false : true; 와 같은 의미
}

const init = () => {
  loginForm.addEventListener('input',checkAllInput)
  /*
  - loginForm = <form id="loginForm"> ... </form>
  - form 태그를 활용하면 input에 이벤트 헨들러는 하나하나 적용할 필요가 없음
  - 이벤트 버블링 : 이벤트가 발생한 지점에서 상위 태그로 점점 타고 올라감. 
  - 즉, input에서 이벤트가 일어나면 form을 거치게 됨.
  - form 태그는 그런 이벤트를 "위임"받게됨. (이벤트 위임)
  */
};


init();
/*
- init (=initalize) : 초기화
- 다양한 스크립트가 작성되었지만, 실질적으로 longin.js가 시작되는 것은 "여기부터"라는 것을 알려주기 위해 작성
- 즉, Entry ponit
- 필수는 아니지만 명료한 전달을 할 수 있음
*/

 

필수 미션 완료 후, validation같은 추가 미션 조건이 있었지만 필수 사항부터도 확실히 이해 못하고 넘어가는 부분이 많은 것 같아 하나씩 되집어 보기로 했다. 잘하고 있는 걸까.

반응형

댓글