Ich entwickle eine Webanwendung (keine Website mit Seiten mit interessantem Text) mit einer ganz anderen Oberfläche für Berührungen (Ihr Finger verbirgt den Bildschirm, wenn Sie klicken) und Maus (hängt stark von der Schwebevorschau ab). Wie kann ich feststellen, dass mein Benutzer keine Maus hat, um ihm die richtige Benutzeroberfläche zu präsentieren? Ich habe vor, einen Schalter für Leute mit Maus und Berührung zu hinterlassen (wie einige Notebooks).
Die Berührungsereignisfunktion im Browser bedeutet nicht, dass der Benutzer ein Berührungsgerät verwendet (z. B. schneidet Modernizr es nicht ab). Der Code, der die Frage richtig beantwortet, sollte false zurückgeben, wenn das Gerät eine Maus hat, andernfalls true. Bei Geräten mit Maus und Berührung sollte false zurückgegeben werden (nicht nur Berühren).
Nebenbei bemerkt, meine Touch-Oberfläche eignet sich möglicherweise auch nur für Tastaturgeräte. Es ist also eher der Mangel an Maus, den ich erkennen möchte.
Um die Notwendigkeit klarer zu machen, ist hier die API, die ich implementieren möchte:
// Level 1
// The current answers provide a way to do that.
hasTouch();
// Returns true if a mouse is expected.
// Note: as explained by the OP, this is not !hasTouch()
// I don't think we have this in the answers already, that why I offer a bounty
hasMouse();
// Level 2 (I don't think it's possible, but maybe I'm wrong, so why not asking)
// callback is called when the result of "hasTouch()" changes.
listenHasTouchChanges(callback);
// callback is called when the result of "hasMouse()" changes.
listenHasMouseChanges(callback);
quelle
Antworten:
Das Hauptproblem besteht darin, dass Sie die folgenden verschiedenen Klassen von Geräten / Anwendungsfällen haben:
Was noch schlimmer ist, ist, dass man von einigen dieser Klassen zu anderen wechseln kann (Stecker in eine Maus, stellt eine Verbindung zur Tastatur her), oder ein Benutzer scheint sich auf einem normalen Laptop zu befinden, bis er den Bildschirm berührt.
Sie gehen zu Recht davon aus, dass das Vorhandensein von Ereigniskonstruktoren im Browser kein guter Weg ist, um vorwärts zu kommen (und etwas inkonsistent ist). Darüber hinaus ist die Verwendung von Ereignissen selbst kein vollständiger Beweis, es sei denn, Sie verfolgen ein bestimmtes Ereignis oder versuchen nur, einige der oben genannten Klassen auszuschließen.
Angenommen, Sie haben festgestellt, dass ein Benutzer eine echte Mausbewegung ausgegeben hat (nicht die falsche aus Berührungsereignissen, siehe http://www.html5rocks.com/en/mobile/touchandmouse/ ).
Dann was?
Sie aktivieren Schwebestile? Sie fügen weitere Schaltflächen hinzu?
In beiden Fällen erhöhen Sie die Zeit bis zum Glas, da Sie auf das Auslösen eines Ereignisses warten müssen.
Aber was passiert dann, wenn Ihr edler Benutzer entscheidet, dass er seine Maus ausstecken und die volle Berührung ausführen möchte? Warten Sie, bis er Ihre jetzt überfüllte Benutzeroberfläche berührt, und ändern Sie sie dann, nachdem er sich bemüht hat, Ihre jetzt überfüllte Benutzeroberfläche zu lokalisieren?
In Aufzählungszeichen unter Angabe von stucox unter https://github.com/Modernizr/Modernizr/issues/869#issuecomment-15264101
Nebenbei bemerkt: Der Browser weiß, wann ein Benutzer eine Maus einsteckt / eine Verbindung zu einer Tastatur herstellt, setzt sie jedoch nicht JavaScript aus.
Dies sollte Sie zu Folgendem führen:
Die Idee der progressiven Verbesserung trifft hier jedoch recht gut zu. Erstellen Sie eine Erfahrung, die unabhängig vom Kontext des Benutzers reibungslos funktioniert. Nehmen Sie dann Annahmen basierend auf Browserfunktionen / Medienabfragen vor, um Funktionen hinzuzufügen, die im angenommenen Kontext relativ sind. Das Vorhandensein einer Maus ist nur eine von vielen Möglichkeiten, wie verschiedene Benutzer auf verschiedenen Geräten Ihre Website erleben. Erstellen Sie etwas mit Verdienst im Kernel und sorgen Sie sich nicht zu sehr darum, wie Leute auf die Schaltflächen klicken.
quelle
:hover
Elemente und ähnliche Dinge) anzupassen , wenn der Benutzer von der Maus zur Berührung wechselt. Es ist unwahrscheinlich, dass der Benutzer derzeit genau zur gleichen Zeit Maus + Berührung verwendet (ich meine, es ist, als wären 2 Mäuse an denselben Computer angeschlossen, hahaha)Wie wäre es, wenn Sie auf ein Mausbewegungsereignis im Dokument warten. Bis Sie dieses Ereignis hören, nehmen Sie an, dass das Gerät nur eine Berührung oder eine Tastatur ist.
(Wo
listen
undunlisten
delegieren anaddEventListener
oderattachEvent
nach Bedarf.)Hoffentlich würde dies nicht zu viel visuellem Ruck führen, es wäre scheiße, wenn Sie massive Neugestaltungen basierend auf dem Modus benötigen ...
quelle
Ab 2018 gibt es eine gute und zuverlässige Methode, um festzustellen, ob ein Browser über eine Maus (oder ein ähnliches Eingabegerät) verfügt: CSS4-Medieninteraktionsfunktionen, die jetzt von fast jedem modernen Browser (außer IE 11 und speziellen mobilen Browsern) unterstützt werden.
W3C:
Siehe die folgenden Optionen:
Medienabfragen können auch in JS verwendet werden:
Verbunden:
W3-Dokumentation: https://www.w3.org/TR/mediaqueries-4/#mf-interaction
Browserunterstützung: https://caniuse.com/#search=media%20features
Ähnliches Problem: Ermitteln Sie, ob ein Clientgerät die Zustände: hover und: focus unterstützt
quelle
Die Antwort von @ Wyatt ist großartig und gibt uns viel zu denken.
In meinem Fall habe ich mich entschieden, auf die erste Interaktion zu warten, um erst dann ein Verhalten festzulegen. Selbst wenn der Benutzer eine Maus hat, werde ich als Berührungsgerät behandelt, wenn die erste Interaktion eine Berührung war.
In Anbetracht der angegebenen Reihenfolge, in der Ereignisse verarbeitet werden :
Wir können davon ausgehen, dass ein Mausereignis, das vor dem Berühren ausgelöst wird, ein echtes Mausereignis ist, kein emuliertes. Beispiel (mit jQuery):
Das hat bei mir funktioniert
quelle
Es ist nur möglich zu erkennen, ob ein Browser berührungsfähig ist . Es ist nicht möglich festzustellen, ob tatsächlich ein Touchscreen oder eine Maus angeschlossen ist.
Man kann die Verwendung jedoch priorisieren, indem man das Berührungsereignis anstelle des Mausereignisses abhört, wenn die Berührungsfähigkeit erkannt wird.
So erkennen Sie browserübergreifende Berührungsfunktionen:
Dann kann man damit überprüfen:
oder wählen Sie, welches Ereignis Sie hören möchten:
oder verwenden Sie separate Ansätze für Berührung oder Nichtberührung:
Bei der Maus kann man nur erkennen, ob die Maus verwendet wird, nicht, ob sie existiert oder nicht. Man kann ein globales Flag einrichten, um anzuzeigen, dass die Maus durch Verwendung erkannt wurde (ähnlich einer vorhandenen Antwort, jedoch etwas vereinfacht):
(man kann nicht einschließen
mouseup
odermousedown
da dieses Ereignis auch durch Berühren ausgelöst werden kann)Browser beschränken den Zugriff auf System-APIs auf niedriger Ebene, die erforderlich sind, um Funktionen wie die Hardwarefunktionen des Systems, auf dem sie verwendet werden, erkennen zu können.
Es besteht die Möglichkeit, möglicherweise ein Plugin / eine Erweiterung zu schreiben, um auf diese zuzugreifen, aber über JavaScript und DOM ist eine solche Erkennung für diesen Zweck eingeschränkt, und man müsste ein Plugin schreiben, das für die verschiedenen Betriebssystemplattformen spezifisch ist.
Fazit: Eine solche Erkennung kann nur durch eine "gute Vermutung" geschätzt werden.
quelle
Wenn Media Queries Level 4 in Browsern verfügbar ist, können wir die Abfragen "Zeiger" und "Hover" verwenden, um Geräte mit der Maus zu erkennen.
Wenn wir diese Informationen wirklich an Javascript weitergeben möchten, können wir eine CSS-Abfrage verwenden, um bestimmte Stile entsprechend dem Gerätetyp festzulegen, und dann
getComputedStyle
in Javascript verwenden, um diesen Stil zu lesen und den ursprünglichen Gerätetyp daraus abzuleiten.Eine Maus kann jedoch jederzeit angeschlossen oder vom Stromnetz getrennt werden, und der Benutzer möchte möglicherweise zwischen Berührung und Maus wechseln. Daher müssen wir diese Änderung möglicherweise erkennen und anbieten, die Benutzeroberfläche zu ändern, oder dies automatisch.
quelle
any-pointer
undany-hover
lassen Sie alle anwendbaren Gerätefunktionen untersuchen. Schön, einen Blick darauf zu werfen, wie wir dieses Problem in Zukunft lösen könnten! :)Wäre es möglich, den Benutzer einfach zu bitten, auf einen Link oder eine Schaltfläche zu klicken, um die richtige Version der Anwendung einzugeben, da Sie ohnehin eine Möglichkeit zum Wechseln zwischen den Schnittstellen anbieten möchten? Dann könnten Sie sich an ihre Präferenz für zukünftige Besuche erinnern. Es ist kein Hightech, aber es ist 100% zuverlässig :-)
quelle
@SamuelRossille Leider gibt es keine mir bekannten Browser, die die Existenz (oder das Fehlen einer) Maus aufdecken.
Wenn dies gesagt ist, müssen wir nur versuchen, mit unserer bestehenden Option ... Veranstaltungen das Beste zu geben, was wir können. Ich weiß, es ist nicht genau das, wonach Sie suchen ... stimmte zu, dass es derzeit alles andere als ideal ist.
Wir können unser Bestes tun, um herauszufinden, ob ein Benutzer zu einem bestimmten Zeitpunkt eine Maus verwendet oder berührt. Hier ist ein schnelles und schmutziges Beispiel mit jQuery & Knockout:
Sie können jetzt usingMouse () & usingTouch () binden / abonnieren und / oder Ihre Schnittstelle mit der body.mouse- Klasse formatieren . Die Benutzeroberfläche wechselt hin und her, sobald ein Mauszeiger erkannt wird und der Touchstart erfolgt.
Hoffentlich haben wir bald einige bessere Optionen von den Browser-Anbietern.
quelle
Tera-WURFL kann Ihnen die Funktionen des Geräts, das Ihre Site besucht, mitteilen, indem die Browsersignatur mit der Datenbank verglichen wird . Schau es dir an, es ist kostenlos!
quelle
Warum erkennen Sie nicht einfach, ob es Berührungen erfassen und / oder auf Mausbewegungen reagieren kann?
quelle
has_touch = 'ontouchstart' in window
ausreichen und so weiter.Das hat bei mir in einer ähnlichen Situation funktioniert. Nehmen Sie grundsätzlich an, dass der Benutzer keine Maus hat, bis Sie eine kurze Reihe aufeinanderfolgender Mausbewegungen sehen, ohne dazwischen Maus-Downs oder Mouseups zu machen. Nicht sehr elegant, aber es funktioniert.
quelle
Werfen Sie einen Blick auf Modenizr. Eines seiner Merkmale ist Touch
http://modernizr.com/docs/#features-misc
Obwohl ich nicht vollständig getestet habe, scheint es sehr gut zu funktionieren
Auch dies ist von der modernizr Seite http://www.html5rocks.com/en/mobile/touchandmouse/ verlinkt.
quelle
Wie andere bereits betont haben, ist es unzuverlässig, endgültig festzustellen, ob sie eine Maus haben oder nicht. Dies kann sich je nach Gerät leicht ändern. Es ist definitiv etwas, was man mit einem booleschen Richtig oder Falsch nicht zuverlässig machen kann, zumindest auf einer Dokumentenskala.
Berührungs- und Mausereignisse sind exklusiv. Dies kann also etwas dazu beitragen, verschiedene Maßnahmen zu ergreifen. Das Problem ist, dass die Berührungsereignisse näher an den Mausereignissen für Auf / Ab / Verschieben liegen und auch ein Klickereignis auslösen.
Aus Ihrer Frage geht hervor, dass Sie einen Schwebeflug zur Vorschau haben möchten. Darüber hinaus kenne ich keine weiteren Details zu Ihrer Benutzeroberfläche. Ich gehe davon aus, dass Sie mit fehlender Maus eine Vorschau für das Tippen wünschen, während ein Klick aufgrund der Hover-Vorschau eine andere Aktion ausführt.
Wenn dies der Fall ist, können Sie bei der Erkennung etwas faul vorgehen:
Einem Onclick-Ereignis geht immer ein Onmouseover-Ereignis mit der Maus voraus. Notieren Sie sich also, dass sich die Maus über dem Element befindet, auf das geklickt wurde.
Sie können dies mit einem dokumentweiten Ereignis zum Entfernen von Dateien tun. Sie können
event.target
damit aufzeichnen, auf welchem Element sich die Maus befindet. Anschließend können Sie in Ihren Onclick-Ereignissen überprüfen, ob sich die Maus tatsächlich über dem Element befindet, auf das geklickt wird (oder einem untergeordneten Element des Elements).Von dort aus können Sie wählen, ob Sie sich für beide auf das Klickereignis verlassen und je nach Ergebnis eine A- oder B-Aktion ausführen möchten. Die B-Aktion kann nichts sein, wenn einige Touch-Geräte kein Klickereignis ausgeben (stattdessen müssten Sie sich auf ontouch * -Ereignisse verlassen).
quelle
Ich glaube nicht, dass es möglich ist, nur Touch-Geräte zu identifizieren (meines Wissens natürlich). Das Hauptproblem ist, dass alle Maus- und Tastaturereignisse auch von Touch-Geräten ausgelöst werden. Im folgenden Beispiel geben beide Warnungen für Touch-Geräte true zurück.
quelle
true
für'onmousedown' in window
Die beste Idee ist meiner Meinung nach die
mousemove
Hörer (derzeit die beste Antwort). Ich glaube, dass diese Methode ein wenig optimiert werden muss. Es ist wahr, dass berührungsbasierte Browser sogar das Mausbewegungsereignis emulieren, wie Sie in dieser iOS-Diskussion sehen können. Daher sollten wir ein wenig vorsichtig sein.Es ist sinnvoll, dass berührungsbasierte Browser dieses Ereignis nur emulieren, wenn der Benutzer auf den Bildschirm tippt (der Finger des Benutzers ist gedrückt). Dies bedeutet, dass wir während unseres Mausbewegungs-Handlers einen Test hinzufügen sollten, um festzustellen, welche Maustaste während des Ereignisses gedrückt ist (falls vorhanden). Wenn keine Maustaste gedrückt ist, können wir davon ausgehen, dass eine echte Maus vorhanden ist. Wenn eine Maustaste gedrückt ist, bleibt der Test nicht schlüssig.
Wie würde dies umgesetzt werden? Dies Frage zeigt, dass die zuverlässigste Methode, um zu untersuchen, welche Maustaste während einer Mausbewegung gedrückt ist, darin besteht, tatsächlich auf drei Ereignisse auf Dokumentebene zu warten: Mausbewegung, Mausbewegung und Mausbewegung. Das Auf und Ab setzt nur ein globales Boolesches Flag. Der Umzug führt den Test durch. Wenn Sie einen Zug haben und der Boolesche Wert falsch ist, können wir davon ausgehen, dass eine Maus vorhanden ist. Siehe Frage für genaue Codebeispiele.
Ein letzter Kommentar. Dieser Test ist nicht ideal, da er nicht in der Ladezeit durchgeführt werden kann. Daher würde ich eine progressive Verbesserungsmethode verwenden, wie zuvor vorgeschlagen. Standardmäßig wird eine Version angezeigt, die die mausspezifische Hover-Oberfläche nicht unterstützt. Wenn eine Maus erkannt wird, aktivieren Sie diesen Modus zur Laufzeit mit JS. Dies sollte dem Benutzer so nahtlos wie möglich erscheinen.
Um Änderungen in der Benutzerkonfiguration zu unterstützen (dh die Maus wurde getrennt), können Sie sie regelmäßig erneut testen. Obwohl ich glaube, dass es in diesem Fall besser ist, den Benutzer einfach über die beiden Modi zu informieren und die Benutzer manuell zwischen ihnen wechseln zu lassen (ähnlich wie bei der Auswahl für Mobilgeräte / Desktops, die immer rückgängig gemacht werden kann).
quelle
Es wurden einige Tests auf verschiedenen PCs, Linux-, iPhone-, Android-Handys und Registerkarten durchgeführt. Seltsam, dass es keine einfache kugelsichere Lösung gibt. Das Problem tritt auf, wenn einige Benutzer mit Touch und keiner Maus Touch- und Mausereignisse für die Anwendung anzeigen. Da Sie Instanzen nur mit der Maus und nur mit der Berührung unterstützen möchten, möchten Sie beide verarbeiten, dies führt jedoch zu doppeltem Auftreten von Benutzerinteraktionen. Wenn Sie wissen, dass keine Maus auf dem Gerät vorhanden ist, können Sie falsche / eingefügte Mausereignisse ignorieren. Versucht, das Flag zu setzen, wenn MouseMove angetroffen wird, aber einige Browser fälschen MouseMove sowie MouseUp und MouseDown auslösen. Ich habe versucht, Zeitstempel zu untersuchen, fand das aber zu riskant. Fazit: Ich habe festgestellt, dass die Browser, die die gefälschten Mausereignisse erstellt haben, immer einen einzelnen MouseMove unmittelbar vor dem eingefügten MouseDown eingefügt haben. In 99,99% meiner Fälle Wenn Sie auf einem System mit einer echten Maus ausgeführt werden, gibt es mehrere aufeinanderfolgende MouseMove-Ereignisse - mindestens zwei. Verfolgen Sie also, ob das System auf zwei aufeinanderfolgende MouseMove-Ereignisse stößt, und erklären Sie, dass keine Maus vorhanden ist, wenn diese Bedingung nie erfüllt ist. Dies ist wahrscheinlich zu einfach, funktioniert aber bei allen meinen Test-Setups. Ich denke, ich bleibe dabei, bis ich eine bessere Lösung gefunden habe. - Jim W.
quelle
Eine einfache Lösung in jQuery zur Erkennung der Mausnutzung, die das Problem löst, bei dem mobile Geräte auch das Ereignis "Mausbewegung" auslösen. Fügen Sie einfach einen Touchstart-Listener hinzu, um den Mousemove-Listener zu entfernen, damit er bei Berührung nicht ausgelöst wird.
Natürlich könnte das Gerät immer noch Touch AND Mouse sein, aber das oben Gesagte garantiert, dass eine echte Maus verwendet wurde.
quelle
Ich habe gerade eine Lösung gefunden, die ich für ziemlich elegant halte.
quelle
Ich bin auf dasselbe Problem gestoßen, bei dem eine einzelne Berührung auch als Klick registriert wurde. Nachdem ich die Kommentare der am besten bewerteten Antworten durchgelesen hatte, kam ich auf meine eigene Lösung:
Das einzige Problem, das ich gefunden habe, ist, dass Sie scrollen können müssen, um ein Berührungsereignis richtig zu erkennen. Eine einzelne Registerkarte (Berührung) kann Probleme verursachen.
quelle
Ich habe Stunden damit verbracht, dieses Problem für meine Phonegap-App herauszufinden, und mir diesen Hack ausgedacht. Es generiert eine Konsolenwarnung, wenn das ausgelöste Ereignis ein "passives" Ereignis ist, was bedeutet, dass es keine Änderung auslöst, aber es funktioniert! Ich würde mich für Verbesserungsvorschläge oder eine bessere Methode interessieren. Dies ermöglicht mir jedoch effektiv, $ .touch () universell zu verwenden.
quelle
Das Hauptproblem, das ich hier sehe, ist, dass die meisten Touch-Geräte ein Mausereignis zusammen mit dem entsprechenden Touch-Ereignis auslösen (Touchstart -> Mousedown, Touchmove -> Mousemove usw.). Nur für die Tastatur, zuletzt für die modernen, verfügen sie über einen generischen Browser, sodass Sie nicht einmal das Vorhandensein der MouseEvent-Klasse erkennen können.
Die weniger schmerzhafte Lösung wäre meiner Meinung nach, beim Start ein Menü anzuzeigen (mit 'Alt'-Verwaltung nur für Benutzer mit Tastatur) und die Auswahl möglicherweise mit localStorage / cookies / serverside zu speichern oder die gleiche Auswahl beim nächsten Mal beizubehalten Mal kommt der Besucher.
quelle
Ich würde dringend gegen diesen Ansatz empfehlen. Betrachten Sie Geräte mit Touchscreen und Desktop-Größe, und Sie müssen verschiedene Probleme lösen.
Bitte machen Sie Ihre App ohne Maus nutzbar (dh keine Schwebevorschau).
quelle
Ich möchte ein Skript empfehlen, das mir geholfen hat:
Ich hatte alles, was vorgeschlagen wurde, gelesen und ausprobiert, ohne ausreichende Ergebnisse.
Dann habe ich noch etwas nachgeforscht und diesen Code gefunden - device.js
Ich verwende dies auf der Website meines Kunden, um die Existenz von Mäusen zu erkennen:
(
<html>
solltedesktop
Klasse haben) und es scheint ziemlich gut zu sein, und zurtouch
Unterstützung mache ich einfach die regelmäßige Überprüfung'ontouchend' in document
und verwende die Informationen beider Erkennungen, um eine bestimmte Sache anzunehmen, die ich brauche.quelle
Im Allgemeinen ist es besser zu erkennen, ob die Mouseover-Funktion unterstützt wird, als den Betriebssystem- / Browsertyp zu erkennen. Sie können dies einfach folgendermaßen tun:
Stellen Sie sicher, dass Sie Folgendes nicht tun:
Letzterer würde die Methode tatsächlich aufrufen, anstatt ihre Existenz zu überprüfen.
Weitere Informationen finden Sie hier: http://www.quirksmode.org/js/support.html
quelle