ECMAScript | TypeScript

더블 클릭이란 무엇일까

partner_jun 2023. 7. 14. 23:18

의문

더블클릭과 더블탭. 아주 흔하게 사용하고 핸들링하는 제스쳐 이벤트다. 그런데 생각해보면 이상하다. 클릭하고 또다시 클릭한다는 더블 클릭의 기준은 뭘까?
클릭과 터치는 기기에 따라 다른 이벤트로 구분하지만 이 글에서는 같은 동작에 대해 설명하려 하므로 더블 클릭으로 통일한다.
 

클릭

 
 

위키백과에서는

위키백과에 따르면 더블 클릭은 움직임 없이 버튼을 두번 '빠르게' 누르는 것이라고 설명한다.

'빠르게'? 이 빠르게는 대체 어느 정도의 시간일까? 1초? 아니, 1초라기엔 짧다. 100ms? 아니, 그렇게 빠르진 않다.


당연하게도 위키백과에 속도에 대한 부분도 있다. 기본 설정의 윈도우에선 500ms 안에 다시 클릭했을 때 더블 클릭으로 판단한다는 내용이다. 심지어 마우스 설정에서 속도를 변경하는 법에 대해 설명하고 있다. 하지만 웹 개발자에게 있어 os는 독립적이며, 브라우저라는 샌드박스 위의 동작에 대해 알아야 하니 다른 이야기이다.
 
 

W3C에서는

웹의 표준을 기재하는 W3C에서 살펴보면, 더블 클릭에 대해 조금 더 알 수 있다.

클릭 이벤트에 대한 취소는 더블 클릭에 영향을 줘서는 안 된다고 한다.


이곳에도 시간에 대한 이야기는 빠져있다. 더블 클릭의 스펙에 있어 시간은 정해지지 않았다는 것을 알 수 있다! 그러니 클릭간 간격을 10ms로 잡아서 만들어도 표준을 무시한 것은 아니다! 
어찌되었건 W3C를 통해 클릭과 더블 클릭은 다른 이벤트이며, 클릭이 더블클릭 액션에 영향을 주어서는 안 된다는 것을 알 수 있다.
 
 

크로니움에서는

어찌되었건 더블클릭의 시간에 대한 표준이 없다면, 실질적인 표준 규격을 찾을 수밖에 없다. 그 말인즉슨, 오픈소스 브라우저 중 가장 많이 쓰이는 크로니움 소스를 볼 수 밖에 없다는 뜻이다. 사실 코드를 살펴보는 과정이 가장 중요하지만 전혀 다른 이야기이니 생략한다. 
제스처에 대해 정의한 gesture_detector.h 파일을 보면 각 구현에 대한 딜레이를 볼 수 있다.

탭 제스처에 대한 딜레이를 찾았다


더블클릭은 클릭 이후 300ms 이후에 다시 클릭했을 때 발생되는 이벤트라는 것을 알 수 있다. 정의 파일인 h 파일과 구현체인 cc 파일을 살펴보면 더 재미있는 것 몇가지를 알 수 있다.
 
 

첫번째. timeout을 이용한 구현 선언

이는 클릭 이후 300ms가 지나면 클릭 되었다는 상태를 변경하기 때문이다. 우리는 이런 류의 코드에 대해 딱히 생각하고 사용하지 않는다. 이미 일상 속에 깊게 들어온, 아주 흔해 빠진 패턴이다. 심지어 안드로이드 프로그래밍에서는 뒤로 가기 버튼을 연속해서 눌렀을 때 앱이 종료되게 하기 위해 입문 단계에서부터 사용하는 로직이다.

is_repeated_tap이라는 변수를 볼 수 있다

 
 
 

두번째. 움직이지 않고 다시 클릭하는 것이 불가능하니 추가된 코드

double_tap_slop_square는 double_tap_slop을 상하로 갖는 사각형 범위다


특히 모바일 기기는 처음 클릭과 두번째 클릭이 정확히 같은 곳에서 이루어지는 것이 거의 불가능하다. 그렇기 때문에 위키 백과에서 설명한 움직이지 않고 라는 말은 현실적으로 불가능하다. 때문에 크로니움에서는 첫 클릭을 중심으로 100만큼의(dip로 보인다) 사각형 범위를 더블 클릭으로 인식하도록 구현 되어 있다. 한가지 더 봐둘만한 것은 더블 클릭의 최소 딜레이가 40ms라는 것이다. 기기의 문제 등으로 연속해서 클릭이 되는 경우 더블클릭으로 인식되는 것을 막기 위함으로 보인다.
 

세번째. 클릭 동작 자체가 지연 동작한다

생각해보면 당연하다. 더블 클릭 여부를 확인하기 위해 300ms의 여유 시간을 갖고 있으니, 클릭이라는 제스처가 발생하자마자 곧바로 클릭 이벤트를 실행해서는 안 된다. 클릭은 페이지 이동이지만 더블 클릭은 페이지 이동을 취소하는 이벤트일 수도 있기 때문이다. 이 또한 timeout을 이용한 코드로 구현되어 있다.

심지어 shortpress의 timeout은 400ms나 된다


하지만 이는 곧 모든 클릭에 대해 딜레이가 생기는 것을 뜻하고, 예민한 사용자는 브라우저의 동작 자체가 뭔가 답답하게 느끼게 된다. 그래서 크롬에서는 이미 오래전 이 문제를 해결하기 위한 방법을 제시했다. 답은 단순하다. 더블 클릭 동작을 하지 않게 만들고, 딜레이를 없애면 된다. 흔히 더블 클릭을 이용한 화면 확대를 막기 위해 사용하는 메타 태그

<meta name="viewport" content="width=device-width">

를 헤더에 작성하면, 크롬은 더블 클릭 동작에 대해 딜레이를 주지 않고 동작한다.
 

사파리의 코드는 공개되어 있지 않기도 하고 최적화를 위한 다양한 룰이 있을테니 정확히 300ms라고 장담할 수는 없다. 하지만 대부분의 브라우저는 크로니움과 유사할 것이라고 생각된다. 혹은 OS처럼 브라우저 자체의 더블 클릭에 대한 상세 옵션을 제공할 수도 있을 것이다.
 
이전부터 이런 식으로 뭔가 하나씩 찾아보는게 꽤나 많은 편인데, 블로그에는 잘 올리지 않게 된다. 찾아볼땐 재미있지만 찾아보고 무엇인지 알게되면 뭔가 다 귀찮아지는게 문제다.