iPad / iPhone 호버 문제로 인해 사용자가 링크를 두 번 클릭합니다.


125

jquery 마우스 이벤트를 사용하는 몇 번 전에 구축 한 웹 사이트가 있습니다. 방금 ipad를 받았는데 모든 마우스 오버 이벤트가 클릭으로 번역된다는 것을 알았습니다 ... 그래서 예를 들어 하나가 아닌 두 번의 클릭을해야합니다 .. (실제 클릭보다 첫 번째 마우스 오버)

이 문제를 해결할 준비가 된 해결 방법이 있습니까? 아마도 jquery 명령이 마우스 오버 / 아웃 등 대신 사용되었습니다. 감사합니다!


1
당신의 이벤트는 무엇에 묶여 있습니까? 예를 들어 onclick 이벤트가 잘 작동해야합니다. onmouseover, onmouseout 및 CSS : hover는 터치 스크린에 사용할 수있는 "hover"가 없기 때문에 처리하기가 약간 어려운 것입니다. 코드 샘플이 있습니까?
scunliffe 2010-06-14

가능한 한 인터페이스를 다시 생각하는 것이 좋습니다. ipad / iphone의 상호 작용은 PC의 상호 작용을 정확히 반영하지 않으며 유사한 멀티 터치 메커니즘을 사용하는 ipad / iphone / 기타 터치 장치 용으로 작성된 것처럼 웹 사이트를 만드는 것이 현명한 방법 일 것입니다. 그냥 생각.
jer

나는 "jer"에 동의한다. 이것은 이상한 질문입니다. 저는 여기서 해결책이 개인적으로 "해결책"이라고 생각하지 않습니다. 데스크톱 브라우저의 "마우스 호버"를 터치 스크린 브라우저의 "손가락 탭"으로 번역하는 것이 합리적이라고 생각합니다. 번역에 동의하지만 두 번이 아닌 한 번 탭하려면 iPad 이벤트 (예 : "touchstart")에 대한 기능 감지를 수행하고 이벤트 핸들러를 변경합니다. 기능에 따라 다르게 실행되는 기능의 jquery 플러그인 "터치 또는 클릭"종류로 코드를 추출 할 수 있지만 귀하의 웹 사이트 / 앱에 고유 한 것처럼 보입니다.
Andy Atkinson

1
저는 실제로이 번역을 기능이라고 생각합니다. 호버 이벤트를 설정했다면이를 볼 수있는 유틸리티가 있어야합니다. 한 번 탭하면 호버 된 요소가 표시되고 두 번째 탭은 호버 "뒤에있는"링크를 따릅니다.
Aaron

답변:


205

이를 완전히 테스트하지는 않았지만 iOS가 터치 이벤트를 발생시키기 때문에 jQuery 설정에 있다고 가정하면 작동 할 수 있습니다.

$('a').on('click touchend', function(e) {
    var el = $(this);
    var link = el.attr('href');
    window.location = link;
});

아이디어는 Mobile WebKit touchend이 탭이 끝날 때 이벤트를 발생시켜 이벤트를 수신 한 다음 touchend링크에서 이벤트가 발생 하자마자 브라우저를 리디렉션한다는 것 입니다.


17
내 현상금은 어딨어? : P
cduruk 2010-08-06

2
인내심, Padwan. 그래서 효력이 발생하는 데 24 시간이 걸린다고 말했습니다.
Andrew Hedges

2
jQuery를 1.7으로 .on선호된다 .live. 이 답변을 읽은 후 코드 변경 $('a').on('click touchend', function(e) {...})이 훌륭하게 작동 한다는 것을 알았습니다 .
Blazemonger 2012

23
글쎄, 이것은 초기 문제를 해결하지만 새로운 문제를 만듭니다. 이것은 해결책이 아닙니다.
luksak

9
이것은 결함이 있습니다. 링크를 클릭 target="_blank"하면 동일한 창과 새 창에서 열립니다.
rybo111 2013

37

귀하의 질문이 무엇인지 완전히 명확하지는 않지만 마우스의 호버 효과를 유지하면서 더블 클릭을 제거하려는 경우 제 조언은 다음과 같습니다.

  • touchstart및에 호버 효과를 추가합니다 mouseenter.
  • mouseleave, touchmove및 에서 마우스 오버 효과를 제거합니다 click.

배경

마우스를 시뮬레이션하기 위해 Webkit 모바일과 같은 브라우저는 사용자가 터치 스크린 (예 : iPad)에서 손가락을 뗀 경우 다음 이벤트를 발생시킵니다 (출처 : html5rocks.com의 Touch And Mouse ).

  1. touchstart
  2. touchmove
  3. touchend
  4. 300ms 지연, 브라우저는 이것이 두 번 탭이 아니라 한 번 탭인지 확인합니다.
  5. mouseover
  6. mouseenter
    • 참고 하십시오 경우 mouseover, mouseenter또는 mousemove이벤트 페이지 내용을 변경, 다음 이벤트가 실행되지 않습니다.
  7. mousemove
  8. mousedown
  9. mouseup
  10. click

단순히 웹 브라우저에 마우스 이벤트를 건너 뛰도록 지시하는 것은 불가능 해 보입니다.

더 나쁜 것은 마우스 오버 이벤트가 페이지 콘텐츠를 변경하는 경우 Safari 웹 콘텐츠 가이드-이벤트 처리 , 특히 One-Finger 이벤트의 그림 6.4에 설명 된대로 클릭 이벤트가 발생하지 않는다는 것 입니다. 정확히 "내용 변경"은 브라우저와 버전에 따라 다릅니다. iOS 7.0의 경우 배경색 변경은 콘텐츠 변경이 아닙니다 (또는 더 이상 변경되지 않습니까?).

솔루션 설명

요약하자면:

  • touchstart및에 호버 효과를 추가합니다 mouseenter.
  • mouseleave, touchmove및 에서 마우스 오버 효과를 제거합니다 click.

에 대한 작업이 없습니다 touchend.

이 명확하게 마우스 이벤트 작동 : mouseentermouseleave(약간의 버전을 개선 mouseover하고 mouseout) 해고하고, 추가하고 호버를 제거합니다.

사용자가 실제로 click링크 된 경우 호버 효과도 제거됩니다. 이렇게하면 사용자가 웹 브라우저에서 뒤로 버튼을 누르면 제거됩니다.

이것은 터치 이벤트에서도 작동합니다 : touchstart호버 효과가 추가됩니다. 에서 제거되지 '' 'not' ''입니다 touchend. 에 다시 추가 mouseenter되고 이로 인해 콘텐츠 변경이 발생하지 않으므로 (이미 추가됨) click이벤트도 실행되고 사용자가 다시 클릭 할 필요없이 링크를 따라갑니다!

브라우저가 touchstart이벤트 사이에 발생하는 300ms 지연은 click이 짧은 시간 동안 호버 효과가 표시되기 때문에 실제로 유용하게 사용됩니다.

사용자가 클릭을 취소하기로 결정한 경우 손가락을 움직여도 정상적으로 수행됩니다. 일반적으로 이것은 mouseleave이벤트가 발생 하지 않고 호버 효과가 제자리에 남아 있기 때문에 문제 입니다. 고맙게도에서 호버 효과를 제거하면 쉽게 해결할 수 있습니다 touchmove.

그게 다야!

예를 들어 FastClick 라이브러리 를 사용하여 300ms 지연을 제거 할 수 있지만 이는이 질문의 범위를 벗어납니다.

대체 솔루션

다음 대안에서 다음과 같은 문제를 발견했습니다.

  • 브라우저 감지 : 오류가 매우 발생하기 쉽습니다. 장치에 마우스 또는 터치가 있고 두 가지의 조합이 터치 디스플레이가 번식 할 때 점점 더 보편화 될 것이라고 가정합니다.
  • CSS 미디어 감지 : 내가 아는 유일한 CSS 전용 솔루션입니다. 여전히 오류가 발생하기 쉬우 며 장치에 마우스 또는 터치가 있다고 가정하지만 둘 다 가능합니다.
  • 클릭 이벤트 에뮬레이션 touchend: 사용자가 실제로 링크를 클릭 할 의도없이 스크롤 또는 확대 / 축소 만 원하더라도 링크를 잘못 따라갑니다.
  • 변수를 사용하여 마우스 이벤트 억제 : 이는 touchend해당 시점에서 상태 변경을 방지하기 위해 후속 마우스 이벤트에서 if 조건으로 사용되는 변수를 설정합니다 . 변수는 클릭 이벤트에서 재설정됩니다. 터치 인터페이스에서 호버 효과를 원하지 않는 경우 적합한 솔루션입니다. 안타깝게도 touchend다른 이유로 a 가 실행되고 클릭 이벤트가 실행되지 않고 (예 : 사용자가 스크롤하거나 확대 / 축소 된) 마우스로 링크를 따라 가려는 경우 (예 : 마우스와 터치 인터페이스가 모두있는 장치에서) 작동하지 않습니다. ).

추가 읽기

iPad / iPhone 두 번 클릭 문제모바일 브라우저에서 호버 효과 비활성화를 참조하십시오 .


2
보다 정확한 문제 해결을 원하는 사람들에게 가장 좋은 설명 인 것 같습니다. Thanx
안티 플레이어

> iOS7의 배경색에 대한 정보에 대해 특별히 감사드립니다. 나는 이것이 언제 작동하기 시작했는지 알아 내려고 시간을 보냈습니다.
staffang nov.

20

결국 CSS 솔루션이있는 것 같습니다. Safari가 두 번째 터치를 기다리는 이유는 일반적으로 : hover 이벤트에 할당하는 배경 이미지 (또는 요소) 때문입니다. 표시 할 항목이 없으면 문제가 없습니다. 해결책은 예를 들어 상속하기 위해 : hover 배경을 재정의하는 보조 CSS 파일 (또는 JS 접근 방식의 경우 스타일)을 사용하여 iOS 플랫폼을 대상으로 지정하고 마우스 위에 표시 할 요소를 숨기는 것입니다.

다음은 CSS 및 HTML의 예입니다. 마우스 위에 별표 표시된 라벨이있는 제품 블록입니다.

HTML :

<a href="#" class="s"><span class="s-star"></span>Some text here</a>

CSS :

.s {
   background: url(some-image.png) no-repeat 0 0;

}
.s:hover {
   background: url(some-image-r.png) no-repeat 0 0;
}

.s-star {
   background: url(star.png) no-repeat 0 0;
   height: 56px;
   position: absolute;
   width: 72px;
   display:none;
}

.s:hover .s-star {
   display:block;
}

솔루션 (보조 CSS) :

/* CSS */
/* Keep hovers the same or hidden */
.s:hover {
   background:inherit;
}
.s:hover .s-star {
   display:none;
}


이 답변은 배경 이미지에 맞춰져 있지만 간단한 불투명도 변경에 대한 솔루션이 있습니까? 이 솔루션은이를 위해 작동하지 않습니다.
Ian S

5

지나치게 복잡하게 만들 필요가 없습니다.

$('a').on('touchend', function() {
    $(this).click();
});

5

나를 위해 일한 것은 다른 사람들이 이미 말한 것입니다.

hover 또는 mousemove (제 경우에는 이벤트)에 요소를 표시하거나 숨기지 마십시오.

Apple이 말하는 내용은 다음과 같습니다 ( https://developer.apple.com/library/content/documentation/AppleApplications/Reference/SafariWebContent/HandlingEvents/HandlingEvents.html ) :

클릭 가능한 요소는 링크, 양식 요소, 이미지 맵 영역 또는 mousemove, mousedown, mouseup 또는 onclick 핸들러가있는 기타 요소입니다.

사용자가 클릭 가능한 요소를 탭하면 이벤트는 mouseover, mousemove, mousedown, mouseup 및 click의 순서로 도착합니다. 또한 페이지의 내용이 mousemove 이벤트에서 변경되면 시퀀스의 후속 이벤트가 전송되지 않습니다. 이 동작을 통해 사용자는 새 콘텐츠를 탭할 수 있습니다.

따라서 @woop의 솔루션을 사용할 수 있습니다. userAgent를 감지하고 iOS 장치인지 확인한 다음 이벤트를 바인딩합니다. 이 기술은 내 요구에 맞기 때문에 결국 사용하게되었고 원하지 않을 때 호버 이벤트를 바인딩하지 않는 것이 더 합리적입니다.

하지만 ... userAgents를 엉망으로 만들고 hover / mousemove에서 요소를 숨기거나 표시하고 싶지 않다면 다음과 같이 네이티브 자바 스크립트를 사용하여 그렇게 할 수 있다는 것을 알았습니다.

$("body").on("mouseover", function() {
       document.getElementsByTagName("my-class")[0].style.display = 'block'; //show element
       document.querySelector(".my-selector div").style.display = 'none'; // hide element
});

이것은 데스크톱 버전에서 작동하며 모바일 버전에서는 아무 작업도 수행하지 않습니다.

그리고 조금 더 호환성을 위해 ...

$("body").on("mouseover", function() {
   if (document.getElementsByTagName && document.querySelector) { // check compatibility
       document.getElementsByTagName("my-class")[0].style.display = 'block'; //show element
       document.querySelector(".my-selector div").style.display = 'none'; // hide element
    } else {
        $(".my-class").show();
        $(".my-selector div").hide();
    }
});

1
"mousemove 이벤트에서 페이지의 내용이 변경되면 시퀀스의 후속 이벤트가 전송되지 않습니다."라는 비트가 실제로 해냈습니다. 나는 헤더 링크가 콘텐츠의 버튼 (em에 대한 모든 행복한 css3 전환 포함)이 단 한 번의 탭을 요구하는 두 번 탭을 요구하는 페이지를 가졌습니다. 헤더 링크에 호버시 불투명도 : 0에서 불투명도 : 1로 이동 한 유사 요소가있는 것으로 나타났습니다. 그 효과를 제거하면 즉시 문제가 해결되었고 원하는 모양을 여전히 얻을 수있는 CSS 해결 방법을 찾았습니다.
가짜 HAAK

3

cduruk의 솔루션은 매우 효과적 이었지만 내 사이트의 일부에 문제가 발생했습니다. CSS hover 클래스를 추가하기 위해 이미 jQuery를 사용하고 있었기 때문에 가장 쉬운 해결책은 단순히 모바일 장치에 CSS hover 클래스를 추가하지 않는 것입니다 (또는 더 정확하게는 모바일 장치가 아닌 경우에만 추가하는 것입니다).

일반적인 아이디어는 다음과 같습니다.

var device = navigator.userAgent.toLowerCase();
var ios = device.match(/(iphone|ipod|ipad)/);

if (!(ios)) {
    $(".portfolio-style").hover(
        function(){
            $(this).stop().animate({opacity: 1}, 100);
            $(this).addClass("portfolio-red-text");
        },
        function(){
            $(this).stop().animate({opacity: 0.85}, 100);
            $(this).removeClass("portfolio-red-text");
        }
    );
}

* 설명을 위해 코드 축소


1
이것이 바로 답입니다. 다른 "솔루션"은 문제를 해결하지 않습니다. iOS 사파리는 우리가 먼저 호버를 원한다고 생각하는 데 분명히 결함이 있습니다. 다른 OS에는 항목 위로 마우스를 가져갈 때 실제 마우스 오버 기능이 있습니다.
Joshua Pack

이것은 나를 위해 일한 유일한 것입니다. 정말 고맙습니다!
tx291 16.10.08

2

mouseenter대신 시도 하는 것이 현명하다고 생각합니다 mouseover. 바인딩 할 때 내부적으로 사용 .hover(fn,fn)되며 일반적으로 원하는 것입니다.


1

기존 솔루션에 다음과 같은 문제가 있었고 모든 문제를 해결할 수있는 것을 발견했습니다. 이것은 크로스 브라우저, 크로스 디바이스를 목표로하고 있으며 디바이스 스니핑을 원하지 않는다고 가정합니다.

이것이 해결하는 문제

touchstart또는 사용 touchend:

  • 사람들이 콘텐츠를지나 스크롤을 시도하고 스 와이프를 시작할 때이 요소 위에 손가락을 갖다 대면 이벤트가 발생 하여 예기치 않게 액션이 트리거됩니다.
  • 데스크톱에서 마우스 오른쪽 버튼을 클릭하는 것과 유사하게 길게 누르면 이벤트가 실행될 수 있습니다. 예를 들어 클릭 이벤트가 URL X로 이동하고 사용자가 새 탭에서 X를 열기 위해 길게 누르면 사용자는 두 탭에서 X가 열려 있다는 사실을 혼동하게됩니다. 일부 브라우저 (예 : iPhone)에서는 길게 누르기 메뉴가 나타나지 않을 수도 있습니다.

mouseover이벤트를 계속 touchstart해서 트리거 mouseout하는 touchmove것은 덜 심각한 결과를 가져 오지만 일반적인 브라우저 동작을 방해합니다. 예를 들면 다음과 같습니다.

  • 길게 누르면 끝나지 않는 마우스 오버가 트리거됩니다.
  • 대부분의 안드로이드 브라우저에 손가락의 위치를 취급 touchstart유사한 mouseover이다,mouseout 다음 번에 편집touchstart . 따라서 Android에서 마우스 오버 콘텐츠를 보는 한 가지 방법은 관심 영역을 터치하고 손가락을 흔들면서 페이지를 약간 스크롤하는 것입니다. 치료 touchmovemouseout 휴식이.

해결책

이론적 touchmove으로는 으로 플래그를 추가 할 수 있지만 iPhone은 움직임이없는 경우에도 터치 무브를 트리거합니다. 이론적으로, 당신은 단지 비교할 수 touchstarttouchend이벤트 pageX등을 pageY 하지만 아이폰에 더있다touchend pageX 나 없다pageY .

그래서 안타깝게도 모든 기지를 커버하는 것은 조금 더 복잡해집니다.

$el.on('touchstart', function(e){
    $el.data('tstartE', e);
    if(event.originalEvent.targetTouches){
        // store values, not reference, since touch obj will change
        var touch = e.originalEvent.targetTouches[0];
        $el.data('tstartT',{ clientX: touch.clientX, clientY: touch.clientY } );
    }
});
$el.on('touchmove', function(e){
    if(event.originalEvent.targetTouches){
        $el.data('tstartM', event.originalEvent.targetTouches[0]);
    }
});

$el.on('click touchend', function(e){
    var oldE = $el.data('tstartE');
    if( oldE && oldE.timeStamp + 1000 < e.timeStamp ) {
        $el.data('tstartE',false);
        return;
    }
    if( $el.data('iosTouchM') && $el.data('tstartT') ){
        var start = $el.data('tstartT'), end = $el.data('tstartM');
        if( start.clientX != end.clientX || start.clientY != end.clientY ){
            $el.data('tstartT', false);
            $el.data('tstartM', false);
            $el.data('tstartE',false);
            return;
        }
    }
    $el.data('tstartE',false);

이론적 으로는 1000을 근사치로 사용하는 대신 길게 누르는 데 사용되는 정확한 시간을 얻는 방법이 있지만 실제로는 그렇게 간단하지 않으며 합리적인 프록시를 사용하는 것이 가장 좋습니다 .


1

MacFreak의 답변은 나에게 매우 도움이되었습니다. 도움이 될 수있는 몇 가지 실습 코드가 있습니다.

문제 -touchend를 적용 한다는 것은 요소 위로 손가락을 스크롤 할 때마다 스크롤을 계속하려는 경우에도 마치 누른 것처럼 반응한다는 의미입니다.

나는 hovered 버튼을 "강조 표시"하기 위해 일부 버튼 아래의 라인을 페이드 업하는 jQuery로 효과를 만들고 있습니다. 링크를 따라 가려면 터치 장치에서 버튼을 두 번 눌러야한다는 의미가 아닙니다.

버튼은 다음과 같습니다.

<a class="menu_button" href="#">
    <div class="menu_underline"></div>
</a>

"menu_underline"div가 마우스 오버시 페이드 업되고 마우스 아웃시 페이드 아웃되도록합니다. 그러나 터치 장치가 두 번이 아닌 한 번의 클릭으로 링크를 따라갈 수 있기를 바랍니다.

솔루션 -다음은 작동하도록하는 jQuery입니다.

//Mouse Enter
$('.menu_button').bind('touchstart mouseenter', function(){
    $(this).find(".menu_underline").fadeIn();
});

//Mouse Out   
$('.menu_button').bind('mouseleave touchmove click', function(){
    $(this).find(".menu_underline").fadeOut();
});

이 MacFreak에 대한 귀하의 도움에 감사드립니다.


1

빈 리스너를 추가하면 작동한다는 것을 알았습니다. 이유는 묻지 않았지만 iOS 9.3.2가 설치된 iPhone 및 iPad에서 테스트했으며 제대로 작동했습니다.

if(/iPad|iPhone|iPod/.test(navigator.userAgent) && !window.MSStream){
    var elements = document.getElementsByTagName('a');
    for(var i = 0; i < elements.length; i++){
        elements[i].addEventListener('touchend',function(){});
    }
}

1

나는 귀하의 링크에 onmouseover 이벤트가 없다고 "생각합니다". 한 번 탭하면 onmouseover가 활성화되고 두 번 탭하면 링크가 활성화됩니다. 하지만 idk. 저는 iPad가 없습니다. 제스처 / 터치 이벤트를 사용해야한다고 생각합니다.

https://developer.apple.com/documentation/webkitjs


0

나는 같은 문제가 있었지만 터치 장치가 아닙니다. 클릭 할 때마다 이벤트가 트리거됩니다. 이벤트 대기열 등이 있습니다.

그러나 내 솔루션은 다음과 같았습니다. 클릭 이벤트 (또는 터치?)에서 타이머를 설정했습니다. Xms 내에 링크를 다시 클릭하면 false를 반환합니다.

요소 별 타이머를 설정하려면 $.data().

이것은 또한 위에서 설명한 @Ferdy 문제를 해결할 수 있습니다.


이 코드가 어떻게 생겼는지 게시 할 수 있습니까? 클릭 이벤트가 두 번 트리거되는 문제가 있습니다.
fancy

0

Modernizr를 사용하는 경우 앞에서 언급했듯이 Modernizr.touch를 사용하는 것은 매우 쉽습니다.

그러나 저는 안전을 위해 Modernizr.touch와 사용자 에이전트 테스트를 함께 사용하는 것을 선호합니다.

var deviceAgent = navigator.userAgent.toLowerCase();

var isTouchDevice = Modernizr.touch || 
(deviceAgent.match(/(iphone|ipod|ipad)/) ||
deviceAgent.match(/(android)/)  || 
deviceAgent.match(/(iemobile)/) || 
deviceAgent.match(/iphone/i) || 
deviceAgent.match(/ipad/i) || 
deviceAgent.match(/ipod/i) || 
deviceAgent.match(/blackberry/i) || 
deviceAgent.match(/bada/i));

function Tipsy(element, options) {
    this.$element = $(element);
    this.options = options;
    this.enabled = !isTouchDevice;
    this.fixTitle();
};

Modernizr를 사용하지 않는 경우 간단히 Modernizr.touch 위 기능을 다음으로('ontouchstart' in document.documentElement)

또한 사용자 에이전트 iemobile을 테스트하면 Windows Phone보다 감지 된 Microsoft 모바일 장치의 범위가 더 넓어집니다.


0

당신은 사용할 수 있습니다 click touchend,

예:

$('a').on('click touchend', function() {
    var linkToAffect = $(this);
    var linkToAffectHref = linkToAffect.attr('href');
    window.location = linkToAffectHref;
});

위의 예는 터치 장치의 모든 링크에 영향을 미칩니다.

특정 링크 만 대상으로 지정하려면 해당 링크에 클래스를 설정하여이를 수행 할 수 있습니다. 예 :

HTML :

<a href="example.html" class="prevent-extra-click">Prevent extra click on touch device</a>

Jquery :

$('a.prevent-extra-click').on('click touchend', function() {
    var linkToAffect = $(this);
    var linkToAffectHref = linkToAffect.attr('href');
    window.location = linkToAffectHref;
});

건배,

Jeroen


0

요소의 mouseenter / mouseleave / click 상태에 이벤트가 바인딩 된 비슷한 상황이 발생했지만 iPhone에서는 사용자가 요소를 두 번 클릭하여 먼저 mouseenter 이벤트를 트리거 한 다음 다시 클릭 이벤트를 발생시켜야했습니다. .

위와 유사한 방법을 사용하여이 문제를 해결했지만 jQuery $ .browser 플러그인 (jQuery 1.9> 용)을 사용하고 다음과 같이 mouseenter 바인딩 이벤트에 .trigger 이벤트를 추가했습니다.

// mouseenter event
$('.element').on( "mouseenter", function() {
    // insert mouseenter events below

    // double click fix for iOS and mouseenter events
    if ($.browser.iphone || $.browser.ipad) $(this).trigger('click');
});
// mouseleave event
$('.element').on( "mouseleave", function() { 
    // insert mouseout events below
});
// onclick event
$('.element').on( "click", function() {
    // insert click events below
});

.trigger는 iPhone 또는 iPad에서 볼 때 요소를 마우스로 입력 (또는 처음 클릭) 할 때 .click 이벤트 핸들러를 실행하여 요소를 두 번 클릭 할 필요가 없도록합니다. 가장 우아한 솔루션은 아닐 수도 있지만 제 경우에는 훌륭하게 작동하고 이미 제자리에있는 플러그인을 활용하며 기존 이벤트가 이러한 장치에서 작동하도록 코드 한 줄을 추가해야했습니다.

https://github.com/gabceb/jquery-browser-plugin 에서 jQuery $ .browser 플러그인을 얻을 수 있습니다.


0

실수로 링크를 손가락으로 밀 때 리디렉션을 방지하기위한 개선입니다.

// tablet "one touch (click)" X "hover" > link redirection
$('a').on('touchmove touchend', function(e) {

    // if touchmove>touchend, set the data() for this element to true. then leave touchmove & let touchend fail(data=true) redirection
    if (e.type == 'touchmove') {
        $.data(this, "touchmove_cancel_redirection", true );
        return;
    }

    // if it's a simple touchend, data() for this element doesn't exist.
    if (e.type == 'touchend' && !$.data(this, "touchmove_cancel_redirection")) {
        var el = $(this);
        var link = el.attr('href');
        window.location = link;
    }

    // if touchmove>touchend, to be redirected on a future simple touchend for this element
    $.data(this, "touchmove_cancel_redirection", false );
});

0

MacFreak에서 영감을 받아 저에게 맞는 것을 모았습니다.

이 js 방법은 마우스 오버가 ipad에 고정되는 것을 방지하고 경우에 따라 클릭이 두 번의 클릭으로 등록되는 것을 방지합니다. CSS에서 CSS에 : hover 의사 클래스가있는 경우 .hover로 변경합니다. 예를 들어 .some-class : hover를 .some-class.hover로 변경합니다.

ipad에서이 코드를 테스트하여 css 및 js hover 메소드가 어떻게 다르게 작동하는지 확인하십시오 (호버 효과에서만). CSS 버튼에는 멋진 클릭 알림이 없습니다. http://jsfiddle.net/bensontrent/ctgr6stm/

function clicker(id, doStuff) {
  id.on('touchstart', function(e) {
    id.addClass('hover');
  }).on('touchmove', function(e) {
    id.removeClass('hover');
  }).mouseenter(function(e) {
    id.addClass('hover');
  }).mouseleave(function(e) {
    id.removeClass('hover');
  }).click(function(e) {
    id.removeClass('hover');
    //It's clicked. Do Something
    doStuff(id);
  });
}

function doStuff(id) {
  //Do Stuff
  $('#clicked-alert').fadeIn(function() {
    $(this).fadeOut();
  });
}
clicker($('#unique-id'), doStuff);
button {
  display: block;
  margin: 20px;
  padding: 10px;
  -webkit-appearance: none;
  touch-action: manipulation;
}
.hover {
  background: yellow;
}
.btn:active {
  background: red;
}
.cssonly:hover {
  background: yellow;
}
.cssonly:active {
  background: red;
}
#clicked-alert {
  display: none;
}
<button id="unique-id" class="btn">JS Hover for Mobile devices<span id="clicked-alert"> Clicked</span>

</button>
<button class="cssonly">CSS Only Button</button>
<br>This js method prevents hover from sticking on an ipad, and prevents the click registering as two clicks. In CSS, if you have any :hover in your css, change them to .hover For example .some-class:hover to .some-class.hover


0

터치 스크롤을 끊지 않고 링크가 작동하도록하기 위해 jQuery Mobile의 "탭"이벤트로이 문제를 해결했습니다.

    $('a').not('nav.navbar a').on("tap", function () {
        var link = $(this).attr('href');
        if (typeof link !== 'undefined') {
            window.location = link;
        }
    });

0

나는 너무 늦었지만 알고 있지만 이것이 내가 찾은 가장 쉬운 해결 방법 중 하나입니다.

    $('body').on('touchstart','*',function(){   //listen to touch
        var jQueryElement=$(this);  
        var element = jQueryElement.get(0); // find tapped HTML element
        if(!element.click){
            var eventObj = document.createEvent('MouseEvents');
            eventObj.initEvent('click',true,true);
            element.dispatchEvent(eventObj);
        }
    });

이것은 링크 (앵커 태그)뿐만 아니라 다른 요소에도 적용됩니다. 도움이 되었기를 바랍니다.


0

이 짧은 스 니펫이 작동하는 것 같습니다. 링크를 탭하면 클릭 이벤트 트리거 :

  $('a').on('touchstart', function() {
    $(this).trigger('click');
  });

0

다른 답변의 어느 것도 나를 위해 작동하지 않습니다. 내 앱에는 많은 이벤트 리스너, 자체 확인란 및 리스너가없는 링크와 리스너가있는 링크가 있습니다.

나는 이것을 사용한다 :

var selector = "label, a, button";
var timer;
var startX;
var startY;
$(document).on("click", selector, function (e) {
    if ($(this).data("touched") === true) {
        e.stopImmediatePropagation();
        return false;
    }
    return;
}).on("touchend", selector, function (e) {
    if (Math.abs(startX - e.originalEvent.changedTouches[0].screenX) > 10 || Math.abs(startY - e.originalEvent.changedTouches[0].screenY) > 10)
        // user action is not a tap
        return;
    var $this = $(this);
    // Visit: http://stackoverflow.com/questions/1694595/can-i-call-jquery-click-to-follow-an-a-link-if-i-havent-bound-an-event-hand/12801548#12801548
    this.click();
    // prevents double click
    $this.data("touched", true);
    if (timer)
        clearTimeout(timer);
    setTimeout(function () {
        $this.data("touched", false);
    }, 400);
    e.stopImmediatePropagation();
    return false;
}).on("touchstart", function (e) {
    startX = e.originalEvent.changedTouches[0].screenX;
    startY = e.originalEvent.changedTouches[0].screenY;
});

0

이것은 jquery ui 드롭 다운이있을 때 나를 위해 작동합니다.

if (navigator.userAgent.match(/(iPod|iPhone|iPad)/)) {
      $('.ui-autocomplete').off('menufocus hover mouseover');
}

0

hover css 이벤트 내에서 "표시"스타일을 변경하지 마십시오. 나는 호버 상태에서 "display : block"을 가지고 있었다. iOS를 제거한 후 한 번의 탭으로 lins에 갔다. 참고로 최신 IOS 업데이트가이 "기능"을 수정 한 것 같습니다.


0

IPad에서 두 번 클릭을 해결하는 가장 간단한 방법은 미디어 쿼리에서 호버 효과를 위해 CSS를 래핑하는 것입니다 @media (pointer: fine).

@media (pointer: fine) {
  a span {
    display: none;
  }
  a:hover span {
    display: inline-block;
  }
}

이 미디어 쿼리에 래핑 된 CSS는 데스크톱에만 적용됩니다.

이 솔루션에 대한 설명은 여기 https://css-tricks.com/annoying-mobile-double-tap-link-issue/입니다.


-1

다음 navigator.userAgent과 같이 확인할 수 있습니다 .

if(!navigator.userAgent.match(/iPhone/i) || !navigator.userAgent.match(/iPad/i)) {
    //bind your mouseovers...
}

하지만 블랙 베리, 드로이드, 기타 터치 스크린 장치를 확인해야합니다. userAgent에 Mozilla, IE, Webkit 또는 Opera가 포함 된 경우에만 마우스 오버를 바인딩 할 수도 있지만, 예를 들어 Droid가 userAgent 문자열을 다음과 같이보고하기 때문에 일부 장치에 대해서는 여전히 스크리닝해야합니다.

Mozilla/5.0 (Linux; U; Android 2.0.1; en-us; Droid Build/ESD56) AppleWebKit/530.17 (KHTML, like Gecko) Version/4.0 Mobile Safari/530.17

iPhone의 문자열은 비슷합니다. iPhone, iPod, iPad, Android 및 Blackberry 만 검색하면 대부분의 핸드 헬드를 사용할 수 있지만 전부는 아닙니다.


지금은 미친 짓을하지 않으려면 호버 이벤트를 건너 뛰는 스크립트가 최선의 방법이라고 생각합니다. 그래서 첫 번째 대답이 좋았을 것 같습니다 ... 그리고 네가 맞습니다 .. 다른 모든 장치에 대해 생각해보십시오. Jquery 또는 일부 플러그인에 이런 종류의 감지 기능이 있었으면합니다 ..!
Francesco

wurfl.sourceforge.net 이것이 귀하의 대답 일 수 있습니다. 무선 장치의 데이터베이스입니다. jQuery 플러그인만큼 간단하지는 않지만 언제든지 작성할 수 있습니다! xml 파일이 아닌 databse를 사용하는 tera-wurfl.com 도 있습니다. 많이 파지 않았지만 호스팅 된 버전이있을 수 있으므로 wurfl 파일 또는 tera-wurfl 데이터베이스를 최신 상태로 유지하는 것에 대해 걱정할 필요가 없습니다.
jasongetsdown 2015 년

1
내가 뭔가를 놓치고 있거나 iPad 감지에 관한 것이 아니라 iPad의 특정 동작을 해결하는 것에 관한 질문입니까?
Andrew Hedges

5
UA 스니핑? How 90 's : P
Macha

-1

태블릿 및 모바일 장치를 제외하는 CSS 미디어 쿼리를 작성하고 거기에 마우스 오버를 넣으십시오. 이를 위해 jQuery 또는 JavaScript가 실제로 필요하지 않습니다.

@media screen and (min-device-width:1024px) {
    your-element:hover {
        /* Do whatever here */
    }
}

그리고 이것을 html 헤드에 추가하여 해상도가 아닌 실제 픽셀로 계산하는지 확인하십시오.

<meta name="viewport" content="width=device-width, initial-scale=1.0, user-scalable=no" />
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.