포커스와 블러 이벤트
- focus: 요소가 활성 상태가 되어 "데이터 입력 준비" 상태가 되었음을 알립니다. 사용자가 클릭하거나 Tab 키로 이동 시 트리거
- blur: 요소가 포커스를 잃을 때 발생합니다. 다른 요소로 이동하거나 창 밖을 클릭할 때 작동
<!DOCTYPE html>
<html lang="ko">
<head>
<meta charset="UTF-8">
<title>입력 상태 표시</title>
<style>
#nameField { padding: 10px; font-size: 16px; }
.focused { border: 2px solid #42a5f5; }
.invalid { border: 2px solid #ef5350; }
#status { margin-top: 5px; color: #666; }
</style>
</head>
<body>
<label for="nameField">이름:</label>
<input id="nameField" placeholder="3자 이상 입력">
<div id="status"></div>
<script>
const nameField = document.getElementById('nameField');
const status = document.getElementById('status');
// 입력 시작 시 안내 표시
nameField.addEventListener('focus', () => {
nameField.classList.add('focused');
nameField.classList.remove('invalid');
status.textContent = '3자 이상의 이름을 입력하세요.';
});
// 입력 종료 시 검증
nameField.addEventListener('blur', () => {
nameField.classList.remove('focused');
if (nameField.value.length < 3) {
nameField.classList.add('invalid');
status.textContent = '이름이 너무 짧습니다.';
} else {
status.textContent = '유효한 이름입니다.';
}
});
</script>
</body>
</html>
포커스 제어하기
자바스크립트를 사용하면 특정 조건에 따라 요소에 포커스를 주거나 제거할 수 있습니다. 예를 들어, 유효하지 않은 값이 입력되면 해당 필드에 다시 포커스를 주어 사용자가 바로 수정할 수 있도록 할 수 있습니다.
<!DOCTYPE html>
<html lang="ko">
<head>
<meta charset="UTF-8">
<title>비밀번호 확인 포커스</title>
<style>
input { padding: 8px; margin: 5px 0; display: block; }
.error { border: 2px solid #d81b60; }
#feedback { color: #d81b60; }
</style>
</head>
<body>
<input id="password" type="password" placeholder="비밀번호">
<input id="confirm" type="password" placeholder="비밀번호 확인">
<div id="feedback"></div>
<script>
const password = document.getElementById('password');
const confirm = document.getElementById('confirm');
const feedback = document.getElementById('feedback');
confirm.addEventListener('blur', () => {
if (password.value && password.value !== confirm.value) {
confirm.classList.add('error');
feedback.textContent = '비밀번호가 일치하지 않습니다.';
setTimeout(() => confirm.focus(), 0); // 비동기로 포커스 이동
} else {
confirm.classList.remove('error');
feedback.textContent = '';
}
});
</script>
</body>
</html>
포커스 이벤트와 버블링 문제 해결
기본적으로 focus와 blur 이벤트는 버블링되지 않습니다.
캡처링을 이용한 방법
캡처링 단계에서 이벤트를 처리하면 버블링 없이도 상위 요소에서 포커스와 블러를 감지할 수 있습니다.
<div id="inputContainer" style="padding: 10px; border: 1px solid #ccc;">
<input type="text" placeholder="첫 번째 입력">
<input type="text" placeholder="두 번째 입력">
</div>
<script>
const container = document.getElementById('inputContainer');
container.addEventListener('focus', () => {
container.style.backgroundColor = '#e0f7fa';
}, true); // 캡처링 단계에서 실행
container.addEventListener('blur', () => {
container.style.backgroundColor = '';
}, true);
</script>
focusin과 focusout 이벤트 사용
focusin과 focusout은 focus와 blur와 동일한 역할을 하지만 버블링이 발생합니다.
<!DOCTYPE html>
<html lang="ko">
<head>
<meta charset="UTF-8">
<title>포커스 위임</title>
<style>
#formContainer { padding: 15px; border: 1px solid #ccc; width: 300px; }
input { display: block; margin: 10px 0; padding: 5px; }
.active { background: #e3f2fd; }
</style>
</head>
<body>
<div id="formContainer">
<input placeholder="아이디">
<input placeholder="비밀번호">
</div>
<script>
const formContainer = document.getElementById('formContainer');
formContainer.addEventListener('focusin', () => {
formContainer.classList.add('active');
});
formContainer.addEventListener('focusout', () => {
setTimeout(() => {
if (!formContainer.contains(document.activeElement)) {
formContainer.classList.remove('active');
}
}, 0);
});
</script>
</body>
</html>
tabindex로 포커스 확장
기본적으로 <input>, <button>, <a> 등은 포커스가 가능한 반면, <div>, <span> 등은 기본적으로 포커스할 수 없습니다. 그러나 tabindex 속성을 추가하면 종류와 상관없이 포커스 가능한 요소로 만들 수 있습니다.
<!DOCTYPE html>
<html lang="ko">
<head>
<meta charset="UTF-8">
<title>tabindex 활용</title>
<style>
.custom-btn {
padding: 10px 20px; background: #66bb6a; color: white;
display: inline-block; margin: 5px; cursor: pointer;
}
.custom-btn:focus { outline: 3px solid #388e3c; background: #81c784; }
</style>
</head>
<body>
<div class="custom-btn" tabindex="0">버튼 1</div>
<div class="custom-btn" tabindex="0">버튼 2</div>
<p>Tab 키로 포커스 이동을 테스트하세요.</p>
<script>
const buttons = document.querySelectorAll('.custom-btn');
buttons.forEach(btn => {
btn.addEventListener('focus', () => {
console.log(`${btn.textContent}에 포커스`);
});
btn.addEventListener('blur', () => {
console.log(`${btn.textContent}에서 포커스 해제`);
});
});
</script>
</body>
</html>
tabindex 값을 0으로 설정하면, 문서의 기본 순서에 따라 포커스가 이동하며, 사용자가 키보드로도 쉽게 접근할 수 있게 됩니다.
'브라우저' 카테고리의 다른 글
폼 전송하기: submit 이벤트 (1) | 2025.02.21 |
---|---|
폼 데이터 변경 이벤트 조작하기 (0) | 2025.02.21 |
폼 조작 하기 (0) | 2025.02.20 |
스크롤 이벤트 제어 (0) | 2025.02.20 |
키보드 이벤트: keydown과 keyup의 활용 (0) | 2025.02.20 |