티스토리 뷰

HTML 태그들 중에서 특별히 input 태그는 일반적으로 글을 입력하는 텍스트 타입과 입력값을 자동으로 가려주는 패스워드 타입, 그리고 단순히 클릭이 가능한 버튼 타입과 클릭을 통해서 선택과 해지가 가능한 체크박스 타입도 있습니다.

이 밖에도 다양한 타입들이 있지만 우리가 평소에 많이 접할 수 있는 타입은 이정도로 볼 수 있습니다.

/**
 * [input 태그 다루기]
 *  
 * > 포커스 이벤트
 * focusin: 요소에 포커스가 되었을 때
 * focusout: 요소에 포커스가 빠져나갈 때
 * focus: 요소에 포커스가 되었을 때 (버블링 x)
 * blur: 요소에 포커스가 빠져나갈 때 (버블링 x)
 * 
 * > 입력 이벤트
 * input: 사용자가 입력을 할 때
 * change: 요소의 값이 변했을 때
 */

가장 먼저 살펴볼 이벤트는 focus와 관련된 이벤트 입니다.

다른 태그들과 다르게 input 태그는 태그의 이름 그대로 입력의 역할을 하기 때문에 사용자의 키보드나 마우스 동작에 반응하는 특징이 있습니다. 그래서 클릭을 해보면 CSS로 강제로 지워주지 않는 이상 파란 테두리로 강조가 됩니다.

이게 사용자의 동작에 반응할 준비가 되었다는 뜻이고 이 상황을 focus되었다 라고 말합니다.

 

그래서 이렇게 form이라는 id를 가진 태그에다가 focusin과 focusout 타입으로 이벤트 타입과 타겟을 출력해 주는 핸들러를 등록해 주면 코드를 실행했을 때 콘솔에 input 태그에 focus가 되면 focusin 그리고 다른 요소로 focus가 옮겨지면 focusout과 focusin이 같이 발생하는 모습을 확인할 수 있습니다.

const el = document.querySelector('#form');

function printEventType(e) {
  console.log('type:', e.type);
  console.log('target:', e.target);
  console.log('---------');
}

el.addEventListener('focusin', printEventType);
el.addEventListener('focusout', printEventType);

참고로 포커스 이벤트에는 똑같은 원리로 동작하는 focus와 blur라는 이벤트도 있는데요.

이 두 이벤트의 특징은 버블링이 되지 않는다는 점입니다.

el.addEventListener('focus', printEventType);
el.addEventListener('blur', printEventType);

이벤트 타입을 focus와 blur로 수정해서 코드를 실행해보면 focus가 일어나도 이벤트 핸들러가 동작하지 않는 모습을 볼 수 있습니다. 이 form id를 가진 태그 자체는 일반 div 태그이기 때문에 focus가 가능하지가 않고 focus와 blur 이벤트는 버블링이 일어나지 않기 때문에 이벤트 위임을 활용하지 못한 결과라고 볼 수 있습니다. 그래서 요소에 접근하는 대상을 form id를 가진 요소가 아니라 좀 더 구체적이고 focus가 가능한 username으로 바꿔주면 저장하고 실행했을 때 이제는 username id를 가진 태그에 한해서 focus와 blur 이벤트가 동작하는 것을 볼 수 있습니다.

const el = document.querySelector('#username');

지금처럼 여러 개의  input 태그가 있을 때 이벤트를 다루는 효율을 생각하면 focusin과 focusout을 사용하는 것이 좀 더 효과적이지만 focus와 blur가 필요한 상황이 생길 수도 있으니까 같이 참고해두면 좋을 것 같습니다.

 

자 그럼 일단 이 focus 타입은 다시 focusin과 focusout으로 바꿔주고 다음은 입력과 관련된 이벤트를 살펴보겠습니다.

el.addEventListener('focusin', printEventType);
el.addEventListener('focusout', printEventType);

input과 change라는 이벤트입니다. input은 말 그대로 사용자가 어떤 값을 입력하는 순간에 이벤트가 발생하고 change는 요소의 값이 변했을 때 이벤트가 발생합니다. 일단 username은 다시 form으로 바꿔주고 여기 아래 input과 change 타입으로 이벤트 핸들러를 등록해 주겠습니다.

el.addEventListener('input', printEventType);
el.addEventListener('change', printEventType);

그러고 나서 input 태그를 클릭하면 먼저 focusin이 발생하고 어떤 값을 입력하는 순간 이렇게 input 타입 이벤트가 발생합니다. 키보드 이벤트와 비슷해 보이지만 input은 말 그대로 어떤 값이 입력될 때 발생하기 때문에 esc나 시프트 같은 입력과 관련 없는 key에는 이벤트가 발생하지 않는다는 차이가 있습니다.

 

그래서 이러한 특징들을 잘 기억해두었다가 상황에 맞게 필요한 이벤트를 적절히 활용하는 것이 좋습니다.

그런데 요소의 값이 변했들 때 발생한다는 change 이벤트는 아직 발생하지 않습니다.

 

간혹 이렇게 값을 입력할 때 이 input 태그의 안에 값이 변한다고 생각해서 input 이벤트 타입과 change 이벤트 타입이 같은 원리로 동작한다고 오해하는 경우가 있습니다. change 이벤트는 입력이 시작되기 전 값과 완료되었을 때 값 사이에 차이가 있을 때만 발생합니다. 그래서 처음 input 태그에 focus를 두고 어떤 값을 입력할 때는 input 태그의 값이 입력 중인 상태로 평가되기 때문에 최종적으로 입력이 완료되었다는 암시를 주어야 되는데요.

일반적으로 이렇게 focus가 빠져나갈 때 입력이 완료되었다고 판단해서 change 이벤트가 focusout 직전에 발생합니다.

그러면 또 focusout이나 혹은 blur 이벤트와 비슷해 보입니다.

차이점은 실제로 값이 변했을 때 발생하기 때문에 focus만 왔다 갔다 하면 change 이벤트가 발생하지 않습니다.

참고로 input 태그에서 값을 입력하다가 엔터 키를 누르는 것도 입력이 끝났다라고 인식하기 때문에 focus를 잃지 않고 change 이벤트를 발생시킬 수도 있으니까 이 부분도 참고하면 좋을 것 같습니다.

공지사항
최근에 올라온 글
최근에 달린 댓글
Total
Today
Yesterday
링크
«   2024/05   »
1 2 3 4
5 6 7 8 9 10 11
12 13 14 15 16 17 18
19 20 21 22 23 24 25
26 27 28 29 30 31
글 보관함