클릭이 click
가 아닌 경우는 언제인가요? 복잡한 사용자 인터페이스를 개발하는 웹 개발자에게 이는 추상적인 철학적 질문이 아닙니다. 맞춤 마우스 입력 동작을 구현하는 경우 사용자 의도를 염두에 두는 것이 중요합니다. 예를 들어 사용자가 마우스 가운데 버튼으로 링크를 클릭하면 해당 링크의 콘텐츠가 포함된 새 탭을 열려고 했다고 가정하는 것이 합리적입니다. 사용자가 임의의 UI 요소를 가운데 클릭하는 경우 실수로 클릭했다고 가정하고 해당 입력을 무시하는 것이 좋습니다. 기본 버튼 클릭은 UI의 응답을 트리거할 것으로 예상됩니다.
약간 번거롭지만 단일 click
이벤트 리스너를 통해 이러한 미묘한 상호작용을 모델링할 수 있습니다. MouseEvent
의 button
속성을 명시적으로 확인하여 기본 버튼을 나타내는 0
로 설정되었는지 아니면 다른 것으로 설정되었는지 확인해야 합니다. 일반적으로 1
는 가운데 버튼을 나타냅니다. 하지만 button
속성을 명시적으로 확인하는 개발자는 많지 않으므로 어떤 버튼을 눌렀는지와 관계없이 모든 click
를 동일하게 처리하는 코드가 됩니다.
Chrome 55부터 기본 버튼이 아닌 버튼으로 클릭할 때마다 auxclick
라는 새로운 유형의 MouseEvent
가 실행됩니다. 이 새 이벤트와 함께 click
이벤트의 동작도 이에 따라 변경됩니다. 기본 마우스 버튼을 누를 때만 실행됩니다. 이러한 변경사항을 통해 웹 개발자가 MouseEvent.button
속성을 구체적으로 확인하지 않고도 관심 있는 클릭 유형에만 응답하는 이벤트 핸들러를 더 쉽게 작성할 수 있기를 바랍니다.
거짓양성 감소
앞서 언급한 바와 같이 auxclick
를 만든 한 가지 이유는 '중간 클릭으로 탭 열기' 동작을 실수로 재정의하는 맞춤 click
핸들러를 배포하지 않기 위해서였습니다. 예를 들어 History API를 사용하여 위치 표시줄을 다시 작성하고 맞춤 단일 페이지 탐색을 구현하는 click
이벤트 핸들러를 작성했다고 가정해 보겠습니다. 다음과 같이 표시될 수 있습니다.
document.querySelector('#my-link').addEventListener('click', event => {
event.preventDefault();
// ...call history.pushState(), use client-side rendering, etc....
});
커스텀 로직은 마우스의 기본 버튼으로 트리거될 때는 의도한 대로 작동할 수 있지만 가운데 버튼을 클릭할 때 이 코드가 실행되면 사실상 거짓양성이 됩니다. 새 동작이 도입되기 전에는 새 탭을 여는 기본 작업이 방지되어 사용자의 기대에 부합하지 않았습니다.
핸들러 시작 부분에서 event.button === 0
를 명시적으로 확인하고 해당하는 경우에만 코드를 실행할 수 있지만, 이를 잊어버리거나 그렇게 해야 한다는 사실을 깨닫지 못하기 쉽습니다.
필요한 코드만 실행
거짓양성이 줄어드는 반면 auxclick
콜백은 기본 마우스 버튼이 아닌 버튼이 실제로 클릭된 경우에만 실행됩니다. 예를 들어 새 탭을 열기 전에 적절한 대상 URL을 계산해야 하는 코드가 있는 경우 auxclick
를 리슨하고 콜백에 해당 로직을 포함할 수 있습니다. 기본 마우스 버튼을 클릭할 때 실행 오버헤드가 발생하지 않습니다.
브라우저 지원 및 호환성
이 새로운 동작은 현재 Chrome 55에서만 구현됩니다. 초기 제안서에 언급된 대로 웹 개발자 커뮤니티의 의견 (긍정적이든 부정적이든)을 보내주시면 감사하겠습니다. GitHub 문제를 제출하면 표준화 프로세스를 담당하는 담당자와 의견을 공유할 수 있습니다.
그동안 개발자는 auxclick
가 널리 사용될 때까지 기다리지 않고도 마우스 이벤트 처리에 관한 몇 가지 권장사항을 따를 수 있습니다. click
이벤트 핸들러 시작 시 MouseEvent.button
속성의 값을 확인하면 적절한 조치를 취할 수 있습니다. 다음 패턴은 auxclick
에 대한 기본 지원 여부에 관계없이 기본 클릭과 보조 클릭을 다르게 처리합니다.
function handlePrimaryClick(event) {
// ...code to handle the primary button click...
}
function handleAuxClick(event) {
// ...code to handle the auxiliary button click….
}
document.querySelector('#my-link').addEventListener('click', event => {
if (event.button === 0) {
return handlePrimaryClick(event);
}
// This provides fallback behavior in browsers without auxclick.
return handleAuxClick(event);
});
// Explicitly listen for auxclick in browsers that support it.
document.querySelector('#my-link').addEventListener('auxclick', handleAuxClick);