focus
이벤트를 발생시킨다.index.html
의 input id="id"
태그가 아이디 입력 태그임을 찾는다.const $idTag = document.getElementById('id')
window
가 load
되는 이벤트 발생시 idTag
에 focus
를 준다.window.addEventListener('load', () => $idTag.focus)
focus out
시 해당 input의 유효성을 검사합니다.가입하기
버튼을 눌렀을 때 모든 필드의 유효성을 검사합니다.모든 필드의 값은 빠짐 없이 입력해야 합니다.
ID, 비밀번호, 비밀번호 확인 필드는 유효성 조건을 충족해야 합니다.
각각 id
, pw
, pw-check
의 id 속성들을 가져온다.
foucsout
이벤트 발생 시 유효성을 검사하는 함수를 각각 만든다.
RegExp
를 사용한다.const ID_REGEX = new RegExp(****^[a-z0-9_-]{5, 20}$)
** const PW_REGEX = new RegExp(^[A-Za-z0-9]{8, 16}$)
focusout
이벤트 발생 시 함수를 넘겨주고, 가입하기
버튼 클릭 시에도 모든 유효성 검사를 실행한다.const validateId = (value) => {
const isValidId = ID_REGEX.test(value)
if (!isValidId)
}
const validatePw = (value) => {
const isValidPw = PW_REGEX.test(value);
if (!isValidPw)
}
const validatePwCheck = (value) => {
const isValidPwCheck = $pw.value === value;
if (!isValidPwCheck)
}
$idTag.addEventListener('focusout', validateId($idTag.value))
$pw.addEventListener('focusout', validatePw($pw.value));
$pwCheck.addEventListener('focusout', validatePwCheck($pwCheck.value));
$submit.addEventListener('click', (event) => {
event.preventDefault();
validateId($idTag.value);
validatePw($pw.value);
validatePwCheck($pwCheck.value);
})
유효성 조건과 에러 메시지는 아래를 참고해주세요.
id-msg
pw-msg
pw-check-msg
id 속성을 가져온다.focusout
과 click
이벤트(submit)에서 유효하지 않은 값일 경우 에러 메시지를 추가하며 border-red-600 class
추가 const ID_ERROR_MSG = {
required: '필수 정보입니다.',
invalid: '5~20자의 영문 소문자, 숫자와 특수기호(_),(-)만 사용 가능합니다.',
};
const validateId = (value) => {
let isValidId;
if (value.length === 0)
isValidId = 'required';
isValidId = (ID_REGEX.test(value) ? true : 'invalid');
if (isValidId !== true)
{
$idTag.classList.add('border-red-600');
$idMsg.innerText = ID_ERROR_MSG[isValidId];
} else {
$idTag.classList.remove('border-red-600');
$idMsg.innerText = '';
}
}
pw
pwCheck
도 비슷한 로직으로 에러 메시지를 변경하여 추가한다.dialog
: 대화 상자 (상호 작용) DOM을 이용하여 모달 창을 제어한다.dialog.showModal()
: 대화 상자에 적용된 css
를 포함하여 모달을 open한다.dialog.close()
: 대화 상자를 닫는다.submit
버튼을 클릭한 후 유효성 검사 완료하고 모달을 오픈하도록 한다.const modal = document.getElementById('modal');
submit
의 이벤트 리스너에서 유효성 검사를 마친 뒤 그 값이 모두 true
라면 confirmId/pw
값에 각각 id와 pw 값을 입력해주고 modal
을 오픈해준다.approve/cancelBtn
들이 각각 click
이벤트 발생 시 가입 알림 혹은 modal.close()
를 해준다.$submit.addEventListener('click', (event) => {
event.preventDefault()
const isValidForm =
validateId($idTag.value) === true &&
validatePw($pw.value) === true &&
validatePwCheck($pwCheck.value) === true
if (isValidForm) {
$confirmId.innerText = $idTag.value
$confirmPw.innerText = $pw.value
$modal.showModal()
}
})
$cancelBtn.addEventListener('click', () => {
$modal.close()
})
$approveBtn.addEventListener('click', () => {
window.alert('가입되었습니다.')
$modal.close()
})
기본 폰트 사이즈를 기준으로 1px씩 폰트 사이즈를 조절할 수 있는 기능을 구현해주세요.
(최소: 12px, 최대: 20px)
+
버튼 비활성화+
-
버튼에 해당하는 DOM을 가져온다.
버튼에 click
이벤트 발생 시 font-size를 조절한다.
회원가입 폼 모든 요소의 font-size를 조절할 수 있는 DOM (html)을 찾는다.
document.documentElement
로 html
요소를 가져온다.rem
단위 : 상대 길이 단위로 루트 요소(html)의 글꼴 크기에 따라 크기를 조절한다.inline
으로 작성하지 않은 style에 대해 가져올 수 없기 때문에 Window.getComputedStyle()
메소드를 사용하여 폰트 사이즈를 확인할 수 있다.$increaseFontBtn.addEventListener('click', () => {
onClickFontSizeControl('increase')
})
$decreaseFontBtn.addEventListener('click', () => {
onClickFontSizeControl('decrease')
})
const onClickFontSizeControl = (flag) => {
const fontSize = $getHtmlFontSize()
let newFontSize = flag === 'increase' ? fontSize + 1 : fontSize - 1
$html.style.fontSize = newFontSize
$decreaseFontBtn.disabled = newFontSize <= MIN_FONT_SIZE
$increaseFontBtn.disabled = newFontSize >= MAX_FONT_SIZE
}
id
pw
pwCheck
의 유효성 검사하는 함수의 유사 기능을 하나의 함수로 재구현한다.
// 3개의 비슷한 기능을 하는 함수 찾기
const ID_ERROR_MSG = {
required: '필수 정보입니다.',
invalid: '5~20자의 영문 소문자, 숫자와 특수기호(_),(-)만 사용 가능합니다.',
}
const PW_ERROR_MSG = {
required: '필수 정보입니다.',
invalid: '8~16자 영문 대 소문자, 숫자를 사용하세요.',
}
const PW_CHECK_ERROR_MSG = {
required: '필수 정보입니다.',
invalid: '비밀번호가 일치하지 않습니다',
}
const checkIdRegex = (value) => {
if (value.length === 0) return 'required'
return ID_REGEX.test(value) ? true : 'invalid'
}
const checkPwRegex = (value) => {
if (value.length === 0) return 'required'
return PW_REGEX.test(value) ? true : 'invalid'
}
const checkPwCheckRegex = (value) => {
if (value.length === 0) return 'required'
else {
return $pw.value === value ? true : 'invalid'
}
}
//리팩토링 후
const ERROR_MSG = {
require: '필수 정보입니다.',
invalidId:
'5~20자의 영문 소문자, 숫자와 특수기호(_),(-)만 사용 가능합니다.',
invalidPw: '8~16자 영문 대 소문자, 숫자를 사용하세요.',
invalidPwCheck: '비밀번호가 일치하지 않습니다.',
}
const checkRegex = (value, id) => {
if (value.length === 0) return 'required' //공통된 로직
switch (id) {
case 'id':
return ID_REGEX.test(value) ? true : 'invalidId'
case 'pw':
return PW_REGEX.test(value) ? true : 'invalidPw'
case 'pw-check':
return $pw.value === value ? true : 'invalidPwCheck'
}
}
각각 유효성 검사 후 에러 메시지를 출력하는 부분도 유사한 기능을 하나의 메소드로 재구현한다.
//리팩토링 전
const validateId = (value) => {
let isValidId = checkRegex(value, 'id')
if (isValidId !== true) {
$idTag.classList.add('border-red-600')
$idMsg.innerText = ERROR_MSG[isValidId]
} else {
$idTag.classList.remove('border-red-600')
$idMsg.innerText = ''
}
return isValidId
}
const validatePw = (value) => {
let isValidPw = checkRegex(value, 'pw')
if (isValidPw !== true) {
$pw.classList.add('border-red-600')
$pwMsg.innerText = ERROR_MSG[isValidPw]
} else {
$pw.classList.remove('border-red-600')
$pwMsg.innerText = ''
}
return isValidPw
}
const validatePwCheck = (value) => {
let isValidPwCheck = checkRegex(value, 'pw-check')
if (isValidPwCheck !== true) {
$pwCheck.classList('border-red-600')
$pwCheckMsg.innerText = ERROR_MSG[isValidPwCheck]
}
return isValidPwCheck
}
//리팩토링 후
const checkValidation = (target, msgTarget) => {
const isValid = checkRegex(target)
if (isValid !== true) {
target.classList.add('border-red-600')
msgTarget.innerText = ERROR_MSG[isValid]
} else {
target.classList.remove('border-red-600')
msgTarget.innerText = ''
}
return isValid
}