혼자 정리
blur 이벤트 발생지가 window내부인지 외부인지 구분하기 본문
상황
리액트에서 직접 검색할 수 있는 드랍다운을 커스텀으로 구현.
onBlur 속성에 핸들러를 달아서 인풋 바깥을 클릭했을 때 드랍다운이 닫히도록 하고자 했음
const onBlur = useCallback(() => {
// 드랍다운 닫는 행동
}, [/* dependencies */]);
return (
<>
// pre-input elements...
<input onBlur={onBlur} {...otherAttributes}/>
// after-input elements...
</>
);
문제점
드랍다운에서 선택(클릭 또는 리턴 키 입력)을 하지 않고 blur이벤트가 발생하는 경우 입력하던 input칸이 초기화되도록 해놓은 상태.
유저는 input에서 중간까지 입력하고 나머지 입력할 것이 생각나지 않아서 다른 창으로 넘어갔다가 오는 경우가 있는데(ex. alt+tab) 이 때도 blur이벤트 발생해서 입력하던 것이 초기화되었음.
적용한 방법
window내부에서 다른 곳으로 focus가 이동한 경우 document.activeElement가 바뀌지만 창 전환하는 경우 바뀌지 않는 점을 이용.
const onBlur = useCallback((e) => {
if (document.activeElement === e.currentTarget) {
return;
}
// 드랍다운 닫는 행동
}, [/* dependencies */]);
return (
<>
// pre-input elements...
<input onBlur={onBlur} {...otherAttributes}/>
// after-input elements...
</>
);
window내부에서 input 요소 외의 다른 요소를 클릭한 경우 document.activeElement
는 클릭한 요소가 되었고, blur이벤트는 input에서 발생했으므로 e.currentTarget
은 input요소가 되었음. 따라서 이 때는 if문에 걸려서 return.
창 전환한 경우 document.activeElement
가 input요소로 유지되어서 if문에 들어오게 됨으로 드랍다운을 닫는 행동을 하지 않게 되었음.
'자바스크립트, 타입스크립트' 카테고리의 다른 글
Node.js의 CommonJS, ESM 모듈 호환성 (0) | 2024.04.01 |
---|---|
[TS] 'satisfies' 오퍼레이터 (0) | 2024.01.09 |
[NestJS] 필터에서 다른 필터로 예외 전달하기 (0) | 2022.09.30 |
[TS] (실수 정리) 파라미터의 타입만 서로 다른 함수의 유니온 (0) | 2022.09.19 |
[JS]Execution Context 기본 개념 (0) | 2021.10.30 |