Je développe une application Web (pas un site Web avec des pages de texte intéressant) avec une interface très différente pour le toucher (votre doigt cache l'écran lorsque vous cliquez) et la souris (repose fortement sur l'aperçu au survol). Comment puis-je détecter que mon utilisateur n'a pas de souris pour lui présenter la bonne interface? Je prévois de laisser un interrupteur pour les personnes ayant à la fois la souris et le toucher (comme certains ordinateurs portables).
La capacité d'événement tactile dans le navigateur ne signifie pas en fait que l'utilisateur utilise un appareil tactile (par exemple, Modernizr ne le coupe pas). Le code qui répond correctement à la question doit renvoyer false si le périphérique dispose d'une souris, true sinon. Pour les appareils avec souris et tactile, il doit renvoyer false (pas uniquement tactile)
En remarque, mon interface tactile pourrait également convenir aux appareils à clavier uniquement, c'est donc davantage le manque de souris que je cherche à détecter.
Pour rendre le besoin plus clair, voici l'API que je cherche à implémenter:
// 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);
la source
Réponses:
Le principal problème est que vous avez les différentes classes d'appareils / cas d'utilisation suivantes:
Ce qui est pire, c'est que l'on peut passer de certaines de ces classes à d'autres (branche une souris, se connecte au clavier), ou un utilisateur peut APPARAÎTRE être sur un ordinateur portable normal jusqu'à ce qu'il atteigne et touche l'écran.
Vous avez raison de supposer que la présence de constructeurs d'événements dans le navigateur n'est pas un bon moyen d'avancer (et c'est quelque peu incohérent). De plus, à moins que vous ne suiviez un événement très spécifique ou que vous n'essayiez d'exclure quelques classes ci-dessus, l'utilisation des événements eux-mêmes n'est pas une preuve complète.
Par exemple, supposons que vous ayez découvert qu'un utilisateur a émis un véritable mousemove (pas le faux des événements tactiles, voir http://www.html5rocks.com/en/mobile/touchandmouse/ ).
Alors quoi?
Vous activez les styles de survol? Vous ajoutez plus de boutons?
Dans tous les cas, vous augmentez le temps passé au verre parce que vous devez attendre qu'un événement se déclenche.
Mais alors que se passe-t-il lorsque votre noble utilisateur décide de débrancher sa souris et de le toucher à fond ... attendez-vous qu'il touche votre interface maintenant bourrée, puis changez-la juste après avoir fait l'effort de localiser votre interface utilisateur maintenant encombrée?
Sous forme de puce, citant stucox à https://github.com/Modernizr/Modernizr/issues/869#issuecomment-15264101
Un aparté: le navigateur sait quand un utilisateur branche une souris / se connecte à un clavier, mais ne l'expose pas à JavaScript .. dang!
Cela devrait vous conduire à ce qui suit:
L'idée de l'amélioration progressive s'applique cependant assez bien ici. Créez une expérience qui fonctionne sans problème, quel que soit le contexte de l'utilisateur. Ensuite, faites des hypothèses basées sur les fonctionnalités du navigateur / les requêtes multimédias pour ajouter des fonctionnalités qui seront relatives dans le contexte supposé. La présence d'une souris n'est que l'une des multiples façons dont différents utilisateurs sur différents appareils utilisent votre site Web. Créez quelque chose qui a du mérite au niveau de son noyau et ne vous inquiétez pas trop de la façon dont les gens cliquent sur les boutons.
la source
:hover
éléments et les choses comme ça) lorsque l'utilisateur passe de la souris au toucher. Il semble peu probable que l'utilisateur utilise actuellement la souris + le toucher exactement au même moment (je veux dire, c'est comme avoir 2 souris connectées au même ordinateur hahaha)Que diriez-vous d'écouter un événement mousemove sur le document. Ensuite, jusqu'à ce que vous entendiez cet événement, vous supposez que l'appareil est tactile ou clavier uniquement.
(Où
listen
etunlisten
déléguer àaddEventListener
ouattachEvent
selon le cas.)Espérons que cela ne conduirait pas à trop de jank visuel, ce serait nul si vous avez besoin de remises en page massives basées sur le mode ...
la source
À partir de 2018, il existe un moyen efficace et fiable de détecter si un navigateur dispose d'une souris (ou d'un périphérique d'entrée similaire): les fonctionnalités d'interaction multimédia CSS4 qui sont désormais prises en charge par presque tous les navigateurs modernes (sauf IE 11 et les navigateurs mobiles spéciaux).
W3C:
Voir les options suivantes:
Les requêtes multimédias peuvent également être utilisées dans JS:
En relation:
Documentation W3: https://www.w3.org/TR/mediaqueries-4/#mf-interaction
Prise en charge du navigateur: https://caniuse.com/#search=media%20features
Problème similaire: détecter si un périphérique client prend en charge: hover et: focus states
la source
La réponse de @ Wyatt est excellente et nous donne beaucoup de matière à réflexion.
Dans mon cas, j'ai choisi d'écouter la première interaction, pour ensuite définir un comportement. Donc, même si l'utilisateur a une souris, je traiterai comme un appareil tactile si la première interaction était un toucher.
Compte tenu de l'ordre donné dans lequel les événements sont traités :
Nous pouvons supposer que si un événement de souris est déclenché avant le toucher, il s'agit d'un événement de souris réel, pas d'émulé. Exemple (en utilisant jQuery):
Cela a fonctionné pour moi
la source
Il est seulement possible de détecter si un navigateur est tactile capable . Il n'y a aucun moyen de savoir si un écran tactile ou une souris est connecté.
On peut cependant donner la priorité à l'utilisation en écoutant l'événement tactile au lieu de l'événement souris si la capacité tactile est détectée.
Pour détecter la fonctionnalité tactile dans plusieurs navigateurs:
Ensuite, on peut utiliser ceci pour vérifier:
ou pour choisir l'événement à écouter, soit:
ou utilisez des approches distinctes pour le toucher et le non-tactile:
Pour la souris, on ne peut détecter que si la souris est utilisée, pas si elle existe ou non. On peut configurer un drapeau global pour indiquer que la souris a été détectée par l'utilisation (similaire à une réponse existante, mais simplifiée un peu):
(on ne peut pas inclure
mouseup
oumousedown
comme ces événements peuvent également être déclenchés par le toucher)Les navigateurs restreignent l'accès aux API système de bas niveau nécessaires pour pouvoir détecter des fonctionnalités telles que les capacités matérielles du système sur lequel il est utilisé.
Il y a la possibilité d'écrire peut-être un plugin / extension pour y accéder mais via JavaScript et DOM une telle détection est limitée à cet effet et il faudrait écrire un plugin spécifique aux différentes plates-formes OS.
Donc en conclusion: une telle détection ne peut être estimée que par une "bonne estimation".
la source
Lorsque Media Queries Level 4 sera disponible dans les navigateurs, nous pourrons utiliser les requêtes "pointer" et "hover" pour détecter les périphériques avec une souris.
Si nous voulons vraiment communiquer ces informations à Javascript, nous pourrions utiliser une requête CSS pour définir des styles spécifiques en fonction du type d'appareil, puis utiliser
getComputedStyle
en Javascript pour lire ce style et en dériver le type d'appareil d'origine.Mais une souris peut être connectée ou débranchée à tout moment, et l'utilisateur peut souhaiter basculer entre le toucher et la souris. Il se peut donc que nous devions détecter ce changement et proposer de changer d'interface ou de le faire automatiquement.
la source
any-pointer
etany-hover
vous permettra d'étudier toutes les capacités applicables de l'appareil. Ravi de voir comment nous pourrions résoudre ce problème à l'avenir! :)Puisque vous envisagez de proposer de toute façon un moyen de basculer entre les interfaces, serait-il possible de demander simplement à l'utilisateur de cliquer sur un lien ou un bouton pour «saisir» la bonne version de l'application? Vous pourrez alors vous souvenir de leur préférence pour les prochaines visites. Ce n'est pas de la haute technologie, mais c'est 100% fiable :-)
la source
@SamuelRossille Aucun navigateur à ma connaissance n'expose l'existence (ou l'absence de souris) d'une souris, malheureusement.
Cela étant dit, nous devons simplement essayer de faire de notre mieux avec notre option existante ... les événements. Je sais que ce n'est pas exactement ce que vous recherchez ... d'accord, il est actuellement loin d'être idéal.
Nous pouvons faire de notre mieux pour déterminer si un utilisateur utilise une souris ou une touche à un moment donné. Voici un exemple rapide et sale utilisant jQuery & Knockout:
Vous pouvez maintenant lier / vous abonner à usingMouse () et usingTouch () et / ou styliser votre interface avec la classe body.mouse . L'interface bascule d'avant en arrière dès qu'un curseur de souris est détecté et au démarrage tactile.
J'espère que nous aurons bientôt de meilleures options de la part des fournisseurs de navigateurs.
la source
Tera-WURFL peut vous indiquer les capacités de l'appareil qui visite votre site en comparant la signature du navigateur à sa base de données. Donnez-lui un coup d'oeil, c'est gratuit!
la source
Pourquoi ne détectez-vous pas simplement s'il a la capacité de détecter les touches et / ou de réagir aux mouvements de la souris?
la source
has_touch = 'ontouchstart' in window
suffit, et ainsi de suite.Cela a fonctionné pour moi dans une situation similaire. Fondamentalement, supposons que l'utilisateur ne dispose pas de souris jusqu'à ce que vous voyiez une courte série de déplacements de souris consécutifs, sans intervention de descente de souris ou de souris. Pas très élégant, mais ça marche.
la source
Jetez un oeil à modenizr l'une de ses fonctionnalités est tactile
http://modernizr.com/docs/#features-misc
Bien que je n'ai pas testé complètement, cela semble fonctionner très bien
Ceci est également lié à partir de la page modernizr http://www.html5rocks.com/en/mobile/touchandmouse/
la source
Comme d'autres l'ont souligné, détecter définitivement si oui ou non ils ont une souris n'est pas fiable. Cela peut facilement changer, en fonction de l'appareil. C'est certainement quelque chose que vous ne pouvez pas faire de manière fiable avec un booléen vrai ou faux, du moins à l'échelle d'un document.
Les événements tactiles et les événements souris sont exclusifs. Cela peut donc aider un peu à prendre différentes mesures. Le problème est que les événements tactiles sont plus proches des événements de montée / descente / déplacement de la souris et déclenchent également un événement de clic.
À partir de votre question, vous dites que vous voulez avoir un survol pour prévisualiser. Au-delà de cela, je ne connais pas d'autres détails sur votre interface. Je suppose qu'avec l'absence de souris, vous voulez qu'un clic pour prévisualiser, tandis qu'un clic effectue une action différente en raison de l'aperçu au survol.
Si tel est le cas, vous pouvez adopter une approche un peu paresseuse de la détection:
Un événement onclick sera toujours précédé d'un événement onmouseover avec une souris. Notez donc que la souris est au-dessus de l'élément sur lequel vous avez cliqué.
Vous pouvez le faire avec un événement onmousemove à l'échelle du document. Vous pouvez utiliser
event.target
pour enregistrer sur quel élément se trouve la souris. Ensuite, à l'intérieur de vos événements onclick, vous pouvez vérifier si la souris est réellement sur l'élément sur lequel vous avez cliqué (ou sur un enfant de l'élément).À partir de là, vous pouvez choisir de vous fier à l'événement de clic pour les deux et d'effectuer une action A ou B en fonction du résultat. L'action B pourrait ne rien être si certains appareils tactiles n'émettent pas d'événement de clic (à la place, vous devrez vous fier aux événements ontouch *).
la source
Je ne pense pas qu'il soit possible d'identifier un appareil tactile uniquement (à ma connaissance bien sûr). Le principal problème est que tous les événements de souris et de clavier sont également déclenchés par des appareils tactiles. Consultez l'exemple suivant, les deux alertes renvoient true pour les appareils tactiles.
la source
true
pour'onmousedown' in window
La meilleure idée à mon avis est l'
mousemove
auditeur (actuellement la meilleure réponse). Je pense que cette méthode doit être légèrement modifiée. Il est vrai que les navigateurs tactiles émulent même l'événement mousemove, comme vous pouvez le voir dans cette discussion iOS , nous devons donc être un peu prudents.Il est logique que les navigateurs tactiles n'émulent cet événement que lorsque l'utilisateur appuie sur l'écran (le doigt de l'utilisateur est baissé). Cela signifie que nous devons ajouter un test lors de notre gestionnaire mousemove pour voir quel bouton de la souris est enfoncé (le cas échéant) pendant l'événement. Si aucun bouton de la souris n'est enfoncé, nous pouvons supposer qu'une vraie souris est présente. Si un bouton de la souris est enfoncé, le test n'est pas concluant.
Alors, comment cela serait-il mis en œuvre? Cette question montre que la méthode la plus fiable pour examiner quel bouton de la souris est enfoncé pendant un déplacement de la souris est en fait d'écouter 3 événements au niveau du document: mousemove, mousedown et mouseup. Le haut et le bas définiront uniquement un indicateur booléen global. Le mouvement effectuera le test. Si vous avez un mouvement et que le booléen est faux, nous pouvons supposer qu'une souris est présente. Voir la question pour des exemples de code exacts.
Un dernier commentaire. Ce test n'est pas idéal car il ne peut pas être effectué au moment du chargement. Par conséquent, j'utiliserais une méthode d'amélioration progressive comme suggéré précédemment. Par défaut, affiche une version qui ne prend pas en charge l'interface de survol spécifique à la souris. Si une souris est découverte, activez ce mode dans le runtime à l'aide de JS. Cela devrait apparaître aussi transparent que possible pour l'utilisateur.
Afin de prendre en charge les changements dans la configuration de l'utilisateur (c'est-à-dire que la souris a été déconnectée), vous pouvez périodiquement effectuer un nouveau test. Bien que je pense qu'il sera préférable dans ce cas de simplement informer l'utilisateur sur les 2 modes et de laisser les utilisateurs basculer manuellement entre eux (un peu comme le choix mobile / bureau qui peut toujours être inversé).
la source
J'ai effectué des tests sur divers PC, Linux, iPhone, téléphones et onglets Android. Bizarre qu'il n'y ait pas de solution simple à l'épreuve des balles. Le problème survient lorsque certains qui ont Touch et pas de souris présentent toujours des événements Touch et Mouse à l'application. Étant donné que vous souhaitez prendre en charge les instances uniquement souris et tactile, vous souhaitez traiter les deux, mais cela entraîne des doubles occurrences d'interactions utilisateur. Si peut savoir que la souris n'est pas présente sur l'appareil, alors peut savoir ignorer les événements de souris faux / insérés. Indicateur de réglage essayé si MouseMove est rencontré, mais certains navigateurs lancent de faux MouseMove ainsi que MouseUp et MouseDown. J'ai essayé d'examiner les horodatages, mais j'ai pensé que c'était trop risqué. Conclusion: j'ai trouvé que les navigateurs qui ont créé les faux événements de souris inséraient toujours un seul MouseMove juste avant le MouseDown inséré. Dans 99,99% de mes cas, lors de l'exécution sur un système équipé d'une vraie souris, il y a plusieurs événements MouseMove consécutifs - au moins deux. Donc, gardez une trace de si le système rencontre deux événements MouseMove consécutifs et déclarez qu'il n'y a pas de souris présente si cette condition n'est jamais remplie. C'est probablement trop simple, mais cela fonctionne sur toutes mes configurations de test. Je pense que je m'en tiendrai jusqu'à ce que je trouve une meilleure solution. - Jim W
la source
Une solution simple dans jQuery pour détecter l'utilisation de la souris, qui résout le problème où les appareils mobiles déclenchent également l'événement «mousemove». Ajoutez simplement un écouteur touchstart pour supprimer l'écouteur mousemove, afin qu'il ne se déclenche pas au toucher.
Bien sûr, l'appareil pourrait toujours être tactile ET souris, mais ce qui précède garantira qu'une vraie souris a été utilisée.
la source
Je viens de trouver une solution que je trouve assez élégante.
la source
J'ai rencontré le même problème, où une seule touche était également enregistrée en tant que clic. Après avoir lu les commentaires des réponses les plus votées, j'ai trouvé ma propre solution:
Le seul problème que j'ai trouvé est que vous devez être capable de faire défiler pour détecter correctement un événement tactile. un seul onglet (toucher) peut poser des problèmes.
la source
J'ai passé des heures à résoudre ce problème pour mon application Phonegap et j'ai inventé ce hack. Il génère un avertissement de console si l'événement déclenché est un événement "passif", c'est-à-dire qu'il n'active aucun changement, mais cela fonctionne! Je serais intéressé par des idées à améliorer ou une meilleure méthode. Mais cela me permet effectivement d'utiliser $ .touch () universellement.
la source
le principal problème que je vois ici est que la plupart des appareils tactiles déclenchent un événement de souris avec le touch one correspondant (touchstart -> mousedown, touchmove -> mousemove, etc.). Pour les claviers seuls, enfin pour les plus modernes, ils ont un navigateur générique donc vous ne pouvez même pas détecter la présence de la classe MouseEvent.
La solution la moins pénible ici serait, à mon avis, d'afficher un menu au lancement (avec gestion 'alt' pour les utilisateurs du clavier uniquement) et peut-être de stocker le choix avec localStorage / cookies / serverside ou bien de garder le même choix le suivant moment où le visiteur vient.
la source
Je déconseille fortement cette approche. Pensez aux appareils à écran tactile de la taille d'un bureau et vous avez un ensemble différent de problèmes à résoudre.
Veuillez rendre votre application utilisable sans souris (c'est-à-dire sans aperçu au survol).
la source
Je voudrais recommander un script qui m'a aidé:
J'avais lu et essayé tout ce qui était suggéré, sans résultats suffisants.
Ensuite, j'ai enquêté un peu plus et j'ai trouvé ce code - device.js
J'utilise ceci dans le site Web de mon client, pour détecter l'existence de la souris:
(
<html>
devrait avoir unedesktop
classe) et cela semble assez bon, et pour letouch
support, je fais juste la vérification régulière'ontouchend' in document
et j'utilise les informations des deux détections pour supposer une chose spécifique dont j'ai besoin.la source
Il est généralement préférable de détecter si la fonction de survol de la souris est prise en charge plutôt que de détecter le type de système d'exploitation / navigateur. Vous pouvez le faire simplement de la manière suivante:
Assurez-vous de ne pas effectuer les opérations suivantes:
Ce dernier appellerait en fait la méthode, plutôt que de vérifier son existence.
Vous pouvez en savoir plus ici: http://www.quirksmode.org/js/support.html
la source