132 Stimmen

iPad/iPhone-Hover-Problem führt dazu, dass der Benutzer doppelt auf einen Link klickt

Ich habe einige Websites, die ich vor einiger Zeit gebaut habe, die Jquery-Mausereignisse verwenden... Ich habe gerade ein iPad bekommen und bemerkt, dass alle Mouse-Over-Ereignisse in Klicks übersetzt werden... so muss ich zum Beispiel zwei Klicks statt einem machen (der erste Hover, dann der eigentliche Klick)

Gibt es einen Workaround, um dieses Problem zu lösen? vielleicht ein Jquery-Befehl, den ich anstelle von mouseover/out etc. verwendet haben sollte. Danke!

4voto

Paul Irish Punkte 44793

Ich denke, es wäre ratsam, zu versuchen mouseenter anstelle von mouseover . Es ist das, was intern verwendet wird, wenn die Bindung an .hover(fn,fn) und ist im Allgemeinen das, was Sie wollen.

3voto

Ich hatte die folgenden Probleme mit den vorhandenen Lösungen und habe etwas gefunden, das alle Probleme zu lösen scheint. Dies setzt voraus, dass Sie für etwas Cross-Browser, Cross-Gerät abzielen, und wollen nicht Gerät sniffing.

Die Probleme, die damit gelöst werden

Mit nur touchstart o touchend :

  • Bewirkt, dass das Ereignis ausgelöst wird, wenn die Personen beim Versuch, am Inhalt vorbeizuscrollen und den Finger zufällig über diesem Element hatten, als sie mit dem Streichen begannen, wodurch die Aktion unerwartet ausgelöst wurde.
  • Kann das Ereignis auslösen auf der Langpresse ähnlich wie beim Rechtsklick auf dem Desktop. Wenn Ihr Klick-Ereignis z. B. zur URL X führt und der Benutzer lange drückt, um X in einer neuen Registerkarte zu öffnen, wird der Benutzer verwirrt sein, weil X in beiden Registerkarten geöffnet ist. Bei einigen Browsern (z. B. iPhone) kann dies sogar dazu führen, dass das Menü bei langem Drücken nicht angezeigt wird.

Auslöser mouseover Veranstaltungen am touchstart y mouseout en touchmove hat weniger schwerwiegende Folgen, beeinträchtigt aber das übliche Verhalten des Browsers, zum Beispiel:

  • Ein langer Druck würde einen Mouseover auslösen, der nie endet.
  • Viele Android-Browser behandeln die Position des Fingers auf touchstart wie ein mouseover das ist mouseout auf der nächsten touchstart . Eine Möglichkeit, Mouseover-Inhalte in Android zu sehen, besteht daher darin, den gewünschten Bereich zu berühren und mit dem Finger zu wackeln, wobei die Seite leicht gescrollt wird. Behandlung von touchmove als mouseout bricht dies.

Die Lösung

Theoretisch könnte man einfach ein Flag hinzufügen mit touchmove aber iPhones lösen touchmove auch dann aus, wenn es keine Bewegung gibt. Theoretisch könnten Sie einfach die touchstart y touchend Veranstaltung pageX y pageY aber auf iPhones gibt es keine touchend pageX o pageY .

Um alle Bereiche abzudecken, wird es also leider ein wenig komplizierter.

$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);

Theoretisch gibt es Es gibt Möglichkeiten, die exakte Zeit für einen Longpress zu ermitteln, anstatt 1000 als Näherungswert zu verwenden, aber in der Praxis ist das nicht so einfach, und es ist am besten, einen vernünftigen Proxy zu verwenden .

3voto

woop Punkte 41

Die Lösung von cduruk war recht effektiv, verursachte aber an einigen Stellen meiner Website Probleme. Da ich bereits jQuery verwendete, um die CSS-Hover-Klasse hinzuzufügen, war die einfachste Lösung, die CSS-Hover-Klasse auf mobilen Geräten einfach nicht hinzuzufügen (oder genauer gesagt, sie NUR hinzuzufügen, wenn sie NICHT auf einem mobilen Gerät ist).

Das war die allgemeine Idee:

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");
        }
    );
}

*Zur Veranschaulichung reduzierter Code

1voto

Ich habe gerade herausgefunden, dass es funktioniert, wenn man einen leeren Listener hinzufügt. Fragen Sie mich nicht warum, aber ich habe es auf iPhone und iPad mit iOS 9.3.2 getestet und es hat gut funktioniert.

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(){});
    }
}

1voto

albert Punkte 8038

Ich "glaube", dass deine Links kein onmouseover-Ereignis haben, bei dem 1 Tippen onmouseover aktiviert und das doppelte Tippen den Link aktiviert. aber idk. Ich habe kein iPad. Ich denke, ya gotta verwenden Geste/Touch-Ereignisse.

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

CodeJaeger.com

CodeJaeger ist eine Gemeinschaft für Programmierer, die täglich Hilfe erhalten..
Wir haben viele Inhalte, und Sie können auch Ihre eigenen Fragen stellen oder die Fragen anderer Leute lösen.

Powered by:

X