모바일 Safari에서 클릭 이벤트에 대한 300ms 지연 제거


89

모바일 Safari는 링크 / 버튼을 클릭 할 때부터 이벤트가 시작될 때까지 클릭 이벤트에 300ms 지연이 있다는 것을 읽었습니다 . 지연의 이유는 사용자가 더블 클릭을 하려는지 확인하기 위해 기다리는 것이지만 UX 관점에서 300ms를 기다리는 것은 종종 바람직하지 않습니다.

이 300ms 지연을 제거하는 한 가지 해결책 은 jQuery Mobile "탭"처리를 사용하는 것입니다. 불행히도 저는이 프레임 워크에 익숙하지 않으며 touchend올바른 방식으로 적용 되는 코드 한두 줄만 필요한 경우 큰 프레임 워크를로드하고 싶지 않습니다 .

많은 사이트와 마찬가지로 내 사이트에는 다음과 같은 많은 클릭 이벤트가 있습니다.

$("button.submitBtn").on('click', function (e) {   
  $.ajaxSubmit({... //ajax form submisssion
});

$("a.ajax").on('click', function (e) {   
  $.ajax({... //ajax page loading
});

$("button.modal").on('click', function (e) {   
      //show/hide modal dialog
});

제가하고 싶은 것은 다음과 같은 단일 코드 스 니펫을 사용하여 모든 클릭 이벤트 에서 300ms 지연을 제거하는 것입니다 .

$("a, button").on('tap', function (e) {
 $(this).trigger('click');
 e.preventDefault();
});

그게 나쁜 / 좋은 생각인가요?



@Pointy 덕분에,이 힘 단지 일 ...
팀 피터슨

"... 분명 UX 관점에서 이건 좋지 않습니다." 나는이 가정에 대해주의 할 것입니다.
Oliver Moran

1
@OliverMoran, 정정 해 주셔서 감사합니다. 방금 그 문장을 편집했습니다. 위의 질문을 참조하십시오.
팀 피터슨

1
해결책이 될 수 있습니다 : stackoverflow.com/a/12969739/1491212
Armel Larcier 2011

답변:


73

이제 일부 모바일 브라우저는 뷰포트를 설정하면 300ms의 클릭 지연을 제거합니다. 더 이상 해결 방법을 사용할 필요가 없습니다.

<meta name="viewport" content="width=device-width, user-scalable=no">

현재 지원되는 Android 용 Chrome입니다 . 안드로이드 파이어 폭스iOS 용 사파리

그러나 iOS Safari에서는 에서 두 번 탭은 확대 / 축소 할 수없는 페이지에서 스크롤 제스처입니다. 이러한 이유로 그들은 300ms 지연을 제거 할 수 없습니다 . 확대 / 축소 할 수없는 페이지에서 지연을 제거 할 수없는 경우 확대 / 축소 가능한 페이지에서 제거 할 가능성이 낮습니다.

Windows Phone 은 또한 확대 할 수없는 페이지에서 300ms 지연을 유지하지만 iOS와 같은 대체 제스처가 없으므로 Chrome 에서처럼 이러한 지연을 제거 할 수 있습니다.다음을 사용하여 Windows Phone에서 지연을 제거 할 수 있습니다.

html {
-ms-touch-action: manipulation;
touch-action: manipulation;
}

출처 : http://updates.html5rocks.com/2013/12/300ms-tap-delay-gone-away

업데이트 2015 년 12 월

지금까지 iOS의 WebKit과 Safari는 사람들이 두 번 탭하여 페이지를 확대 할 수 있도록 한 번의 탭으로 링크 나 버튼을 활성화하기까지 350ms의 지연이있었습니다. Chrome은 이미 몇 달 전에이를 감지하기 위해 더 스마트 한 알고리즘을 사용하여이를 변경했으며 WebKit은 유사한 접근 방식을 따를 것 입니다. 이 기사는 브라우저가 터치 제스처와 함께 작동하는 방식과 브라우저가 오늘날보다 훨씬 더 똑똑해질 수있는 방법에 대한 훌륭한 통찰력을 제공합니다.

2016 년 3 월 업데이트

iOS 용 Safari에서는 두 번째 탭을 감지하는 350ms의 대기 시간이 "빠른 탭"응답을 생성하기 위해 제거되었습니다. width = device-width 또는 user-scalable = no로 뷰포트를 선언하는 페이지에 대해 활성화됩니다. 작성자는 여기에touch-action: manipulation 설명 된대로 CSS 를 사용하여 특정 요소에 대한 빠른 탭 동작을 선택할 수도 있습니다 ( 'Styling Fast-Tap Behavior'제목으로 스크롤) 및 here .


실제로 WP에 대한 터치 이벤트가 있습니다. stackoverflow.com/questions/13396297/…
Cedric Reichenbach

1
예, 내 게시물에 썼 듯이 -ms-touch-action에 의해 제어됩니다.
NoNameProvided

1
홈 페이지 (독립 실행 형)에서 애플리케이션을 실행할 때 iOS에 여전히 문제가 있습니다. 누군가가 그것을 위해 괜찮은 해결 방법을 발견 한 경우, 그것은 매우 환영받을
미구엘 Guardo

1
터치 동작 값을 조작으로 설정하면 원하는 성능에 가장 가깝지만 @MiguelGuardo가 앞서 언급했듯이 iOS의 홈 화면에 웹 페이지를 독립 실행 형 앱으로 추가하면 효과가 사라집니다.
T. Steele

- 사람이있는 UIWebView를 해킹 할 수 있음 stackoverflow.com/questions/55155560/...을
Eazy

43

Financial Times에서 개발 한이 플러그인 -FastClick 은 완벽하게 작동합니다!

추가해야합니다. event.stopPropagation();event.preventDefault();클릭 기능 하거나 바로 뒤에 합니다. 그렇지 않으면 나처럼 두 번 실행될 수 있습니다.

$("#buttonId").on('click',function(event){
    event.stopPropagation(); event.preventDefault();
   //do your magic

});

3
jquery mobile (버전 1.3.2 어쨌든)을 사용하는 경우에는 완벽하지 않습니다. 패널 위젯 github.com/jquery/jquery-mobile/issues/6440
ryan0

event.stopPropagation ()이 바로 제가 처음에이 페이지를 찾은 이유입니다. 완벽하게 작동합니다. 감사합니다!
Lukas

@Jonathan fastclick은 지연 문제가있는 터치 장치에서만 마법을 수행합니다 (그렇지 않으면 자동으로 우회 됨 ). 그러나 단순히 모든 클릭 이벤트 뒤에 stopPropagation& 를 추가하면 preventDefault모든 브라우저의 모든 이벤트 핸들러에 원치 않는 영향을 미칠 수 있습니다.
사용자

17

나는 이것이 오래되었다는 것을 알고 있지만 브라우저에서 "터치"가 지원되는지 테스트 할 수는 없습니까? 그런 다음 "touchend"또는 "click"변수를 만들고 해당 변수를 요소에 바인딩되는 이벤트로 사용 하시겠습니까?

var clickOrTouch = (('ontouchend' in window)) ? 'touchend' : 'click';
$('#element').on(clickOrTouch, function() {
    // do something
});

따라서 코드 샘플은 브라우저에서 "touchend"이벤트가 지원되는지 확인하고 그렇지 않은 경우 "click"이벤트를 사용합니다.

(편집 : "touchend"를 "ontouchend"로 변경)


감사합니다. 저는 이것의 단순함을 좋아합니다. 나는 다른 사람들이 가능한 함정에 대해 차임하는 것을 좋아합니다.
Tim peterson 2013

4
@Andreas Köberle이 답장에서 설명하는 내용 때문에 touchend 이벤트는 클릭 이벤트를 대체 할 수 없습니다. 예를 들어 스크롤하고 손가락이 버튼에서 멈 추면 링크가 트리거됩니다 ...
adriendenat

이것은 지연을 없애기 위해 큰 추가 라이브러리를 포함하지 않고도 멋진 경량 솔루션입니다. 내가 이것에 대해 5 번 투표 할 수 있기를 바랍니다! (스크롤 시나리오에 대해 걱정하지 않는 한!)
tonejac 2014-08-17

2
터치 앤 클릭 이벤트를 지원하는 컴퓨터 / 브라우저의 경우 이는 잘못된 솔루션입니다.
Alexander O'Mara

1
일부 장치는 터치 및 클릭 이벤트를 모두 지원하며 둘 다 다른 상황에서 실행되기를 원합니다. 마우스가있는 일부 창 또는 Android 태블릿에서 사물을 클릭하면 분명히 클릭 이벤트가 발생하지만 탭하면 터치 이벤트도 발생하는 상황을 경험했습니다. 이것은 두 가지 이벤트를 모두 들어야 함을 의미했습니다. 추가적인 복잡한 요소로, 일부 장치는 탭할 때 클릭 이벤트를 합성하므로주의하지 않는 한 두 장치에서 둘 다 수신하면 이벤트 핸들러가 두 번 실행될 수 있습니다.
1800 INFORMATION

12

저는 Hammer.js (Github 페이지) 라는 매우 인기있는 대안을 발견 했는데 이것이 최선의 접근 방식이라고 생각합니다.

Hammer.js는 Fastclick.js (가장 찬성 응답)보다 더 완전한 기능을 갖춘 터치 라이브러리 (많은 스 와이프 명령이 있음)입니다.

하지만주의하세요 : 모바일 장치에서 빠르게 스크롤하면 Hammer.js 또는 Fastclick.js를 사용할 때 UI가 실제로 잠기는 경향이 있습니다. 사이트에 뉴스 피드 또는 사용자가 많이 스크롤하는 인터페이스 (대부분의 웹 앱처럼 보임)가있는 경우 이는 주요 문제입니다. 이러한 이유로 저는 현재 이러한 플러그인을 사용하지 않습니다.


2
Hammerjs를 사용하지 마십시오. 몇 가지 심각한 문제가 있습니다. 예 : github.com/EightMedia/hammer.js/issues/388 github.com/EightMedia/hammer.js/issues/366 적어도 문제가 해결 될 때까지 사용하지 마십시오
Adonis K. Kakoulidis

2

어쨌든 확대 / 축소를 비활성화하면이 작은 지연이 비활성화되는 것 같습니다. 이제 더 이상 두 번 탭할 필요가 없으므로 이해가됩니다.

모바일 웹 페이지에서 확대 / 축소를 "비활성화"하려면 어떻게합니까?

그러나 이것이 가져올 사용성 영향에 유의하십시오. 앱으로 설계된 웹 페이지에는 유용 ​​할 수 있지만보다 일반적인 용도의 '정적'페이지 IMHO에는 사용해서는 안됩니다. 낮은 대기 시간이 필요한 애완 동물 프로젝트에 사용합니다.


1

안타깝게도 이렇게하는 쉬운 방법은 없습니다. 그러니 그냥 사용 touchstart또는 touchend예를 들어 버튼을 클릭 할 때 스크롤 사람이 시작 같은 다른 문제에 당신을 떠날 것입니다. 우리 는 한동안 zepto 를 사용하는데 ,이 정말 좋은 프레임 워크에서도 시간이 지남에 따라 몇 가지 문제가 발생했습니다. 많은 사람들이 닫혀 있지만 간단한 해결책의 분야가 아닌 것 같습니다.

링크에 대한 클릭을 전 세계적으로 처리하는이 솔루션이 있습니다.

   $(document.body).
    on('tap', 'a',function (e) {
      var href = this.getAttribute('href');
      if (e.defaultPrevented || !href) { return; }
      e.preventDefault();
      location.href= href;
    }).
    on('click', 'a', function (e) {
      e.preventDefault();
    });

-@ Andreas, 감사합니다. tap제가 게시 한 일반적인 솔루션을 사용하지 않고 tap요소별로 이벤트를 팩토링하지 않겠습니까?
tim peterson 2012 년

그게 요점이 아닙니다. 요점은 tap혼자서 솔루션 을 구축하려는 것이 아닙니다 . 내 답변을 업데이트하겠습니다.
Andreas Köberle 2012 년

-@ Andreas, 귀하의 답변에 감사드립니다. 많은 클릭 이벤트가 AJAX이므로 기본 이벤트가 이미 차단되었습니다. 이것도 처리하기 위해 답변을 업데이트 하시겠습니까? tap이 경우 내 일반적인 솔루션이 귀하의 솔루션과 동일하게 보일 것 같습니까?
tim peterson 2012 년

1

jquery없이 fastclick 라이브러리없이 쉬운 방법을 찾았습니다. 이것은 나를 위해 작동합니다.

var keyboard = document.getElementById("keyboard");
var buttons = keyboard.children;
var isTouch = ("ontouchstart" in window);
for (var i=0;i<buttons.length;i++) {
    if ( isTouch ) {
        buttons[i].addEventListener('touchstart', clickHandler, false);         
    } else {
        buttons[i].addEventListener('click', clickHandler, false);          
    }
}

0

추가 정보를 제공하기 위해.

iOS 10 <button>에서 내 페이지의 s가 계속 트리거되지 않았습니다. 항상 지연이있었습니다.

fastclick / Hammer / tapjs / click을 touchstart로 대체하려고 시도했지만 모두 실패했습니다.

업데이트 : 이유는 버튼이 가장자리에 너무 가깝기 때문인 것 같습니다! 중앙 근처로 이동하면 지연이 사라집니다!


0

수동 모드를 명시 적으로 선언해야합니다 .

window.addEventListener('touchstart', (e) => {

    alert('fast touch');

}, { passive : true});

0

jQuery에서 "touchend"이벤트를 바인딩 할 수 있으며, 탭 후 즉시 트리거 코드를 설정할 수 있습니다 (키보드의 keydown과 같습니다). 현재 Chrome 및 Firefox 태블릿 버전에서 테스트되었습니다. 터치 스크린 노트북 및 데스크톱 장치의 경우 "클릭"도 잊지 마십시오.

jQuery('.yourElements').bind('click touchend',function(event){

    event.stopPropagation();
    event.preventDefault();

	// everything else
});

당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.