재직하고 있는 회사 프로그램에 버그 제보가 들어왔다.
간단하게 정리하자면
한글을 입력하고 다른 영역을 누르는 경우 최상단으로 스크롤됨
이란 말이였는데, 실제로 동료 개발자와 확인해보니 처음엔 재현이 되질 않았었다.
조금 더 확인해보니, 사용자는 윈도우였고, 한글을 입력하는 도중 해당 input에서 마우스 스크롤로 벗어나 다른 영역을 클릭하면, 입력하던 input으로 돌아가는 것이였다.
mac에서는 재현되지 않았고, ime입력 방식 편집기(Input Method Editor) 한글, 중국어, 일본어 입력 등에 사용된다 입력을 사용하지 않는 영어에선 발생하지 않는 것이였기에 버그가 자명해보였다.
음.. 뭐가 문제지? 콘솔!!
console.log 문제는 오히려 더 아리송해졌다.
우선 테스트 하기 위해 스크롤 이후 버튼 쪽에 콘솔을 찍어보았는데 버튼에 콘솔 로그 자체가 안 찍히는 것이였다.
그리고 스크롤 포지션도 실제 스크롤이 된 위치가 아닌, 클릭 전 스크롤의 위치값을 리턴하고 있었다.
그래서 input 관련 이벤트 리스너를 다 찍어보았다
음..?
input에서 정상인데??
하지만, 벗어난다고 왜 스크롤이 되고, 클릭이 안되는지?는 여전히 잘 알 수가 없었다.
다만, 맥에서는 정상이였고, 확인해보니 영어 입력시에는 문제가 없다는 것을 생각해보면, 윈도우의 ime가 뭔가 이슈가 있는 것 같았다.
아래는 이해를 돕기 위한 영상입니다.
문제를 해결 할때 최선의 접근 방법은 아닌것 같지만, 일단 증상이 나타나는 원인은 파악하지 못해도 일단 증상이 나타난 경우 안 나타난것처럼 하거나, 사용자는 눈치 채지 못하게 하는 트릭은 상당히 유효한 방법이다.
두서 없이 써서 아마 글을 읽는 분은 여기까지 와도 정확히 어떻게 해결해야하는지 혼란이 올 것이다.
요악하자면
한글 입력 도중 스크롤을 해서 다른 요소를 클릭하는 경우,
일단 왜인진 모르겠지만 콘솔을 찍어보았을 때, 전술한 것 처럼 스크롤 값이 제대로 동기화 되지 않고. 실제 보여지는 위치와 다르게 클릭시 스크롤 포지션을 저장하고 있으니, blur 이벤트가 터졌을 때, 다시 스크롤을 해주면 어떨까?
플리커링 현상이 있을 수도 있지만 일단 해보자라는 생각에 진행.
실제 해보니 플리커링 현상도 없었고 스크롤 팅기는 이벤트는 막았다
좋아쓰
그럼 이제 클릭이다.
어? 근데 클릭 이벤트가 아예 안 오는데..
사용자가 클릭한 버튼에 onClick, onMouseDown, onMouseUp
그 어떤 이벤트 리스너를 걸어도, 해당 영역에 이벤트가 오질 않았다.
이벤트가 오질 않으니 사용자가 무엇을 눌렀는지 파악 할 수 없었다.
그럼 일단 전역 리스너를...?
document.body.addEventListener를 통해 등록해보았지만 마찬가지로 이벤트가 아예 전파되질 않았다.
그래서 Mac에서 해보고, 영어 입력 상태에서 해보니 해당 이벤트가 제대로 전파가 되는걸 다시 확인 해보면서 아 한글 떄문이긴 한데.. 아예 브라우저에서 이벤트를 안 던져주는데 어떻게 하지..?
강제로 클릭 이벤트를 발생 시켜야겠네 당연히 의식의 흐름이 진행됐고
new MouseEvent, DispatchEvent를 활용해보았으나, 브라우저 보안 정책에 막혀 실제 사용자 클릭 이벤트처럼 구현하는건 불가능했다.
그래도 머리를 짜내서
elementFromPoint나 현재 마우스 포인트 위치를 확인해서 ime 종료 콜백과 blur 이벤트가 터진다면 input이나 버튼을 클릭한 것처럼 한다.는 어찌저찌 해냈고, 그렇게 되면 인입된 버그 내용은 수정이 가능했지만 이 코드가 과연 다른 엣지 케이스에서 오히려 더 문제가 발생 할 것 같았다.
어찌됐건 클릭 이벤트가 기대한대로 오지 않는다는 것은 자바스크립트 단에서 해결하기 어렵다는것을 생각하게 해주었다.
또한, 크로미움의 경우 ime 맥에서도 버그가 있고, 과거에 이 버그를 VSCode에서 발견하고 수정하려고 했다가 알고보니 크로미움 버그이고, VS Code에서는 크로미움 버그는 수정하지 않는다라는 정책을 발견한적이 있어서 해당 이슈의 수정을 포기한적이 있었는데, 문득 이번것도 그런 게 아닐까 생각이 들었다.
그럼 크롬 구버전에서 해볼까?
당시 142이 최신 버전이였는데, 일단 108이 cef로 마침 설치가 되어있어서 바로 테스트가 가능한 상황이여서, 바로 108버전에서도 테스트 해보았다.
여전히 재현되었고, 윈도우에서만 재현되었다.
크로미움 버그가 거의 확실한데?
아 이건 못 고치겠네..
이런 생각이 들면서도, 아 전에도 Vscode에서 크로미윰 코드 한번 잠깐 봤다가 바로 포기한 이력 있는데 쉽게 포기하는 여장남자 정대만이 될 것인지
턱에 흉터는 남았지만,
이빨 새로 끼우고 머리를 정리한 단발 정대만이 될 것인지의 선택지에서
선택은 자명했다.
고쳐보자!!