Détecter que le navigateur n'a pas de souris et est uniquement tactiles
Je suis le développement d'une webapp (pas un site avec des pages de texte intéressant) avec une très interface différente pour le toucher (le doigt qui cache l'écran lorsque vous cliquez sur) et la souris (s'appuie fortement sur le vol stationnaire d'aperçu).
Comment puis-je détecter que mon utilisateur n'a pas de souris, pour lui présenter le droit de l'interface? J'ai l'intention de laisser un commutateur pour des personnes avec la souris et le toucher (à l'instar de certains ordinateurs portables).
L'événement tactile de capacité dans le navigateur ne peut pas vraiment dire que l'utilisateur est à l'aide d'une touche de l'appareil (par exemple, Modernizr ne coupe pas). Le code qui répond correctement à la question doit retourner false si l'appareil a une souris, true sinon. Pour les appareils avec la souris et le toucher, il doit retourner false (pas touch uniquement)
Comme une note de côté, mon interface tactile peut également être adapté pour le clavier-seuls les appareils, il est donc de plus l'absence de souris, je suis à la recherche à détecter.
À faire de la nécessité de plus en plus clair, voici l'interface que je suis à la recherche à mettre en œuvre:
//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);
- Question connexe: Détecter si le navigateur a clavier/touches fléchées dans la page web
- Je pense que vous devez repenser votre conception si vous voulez une application pour être applicable à la fois de bureau et mobiles/tactiles, mais ont des comportements différents pour chacun. Je ne pense pas que ce que vous êtes après est réellement possible à ce point, car une recherche rapide sur Google pour "javascript détecter la souris" montre moyennement utile de poster sur quirksmode.org pour la détection des différents états de la souris (clics, position, etc), mais des résultats nuls ou non à la souris existe réellement.
- Peut-être que c'est parce que Google n'a pas aidé que j'ai demandé ici.
- Avez-vous essayé document mouseenter de jquery? $(document).mouseenter(function(e) { alert("souris"); });
- La fin de la partie, mais je vais jeter ici que vous devez toujours garder à l'esprit les nombreux appareils de nos jours qui soutiennent à la fois tactile ET la souris
- ma question était assez précisément formulée au sujet ayant pas de souris, comme dans "pas de souris à tous". C'était au moment de présenter le droit de l'interface pour le droit des gens par défaut. pour une application qui pourrait être utilisé sur le terrain, les pieds dans la boue, dans un véhicule en mouvement ou au bureau sur un PC.
- Juste une remarque pour la postérité - si vous cherchez à faire l'inverse (de détecter si la souris est disponible) stackoverflow.com/a/16423486/5056
- Après avoir examiné de près d'une douzaine de pistes prometteuses seulement de rejeter chacun en quelques minutes, cette question me conduire tout à fait magnifiquement dingue.
Vous devez vous connecter pour publier un commentaire.
Le principal problème, c'est que vous avez la suite de différentes classes de périphériques/cas d'utilisation:
Ce qui est pire, c'est qu'on peut la transition de certains de ces classes pour d'autres (les bouchons dans une souris, se connecte à clavier), ou un utilisateur peut APPARAÎTRE sur un ordinateur portable jusqu'à ce qu'ils atteindre et de toucher l'écran.
Vous avez raison de supposer que la présence de l'événement constructeurs dans le navigateur n'est pas une bonne façon d'aller de l'avant (et c'est un peu incohérente). En outre, sauf si vous êtes un suivi très précis de l'événement ou seulement en essayant d'écarter un peu de classes ci-dessus, à l'aide d'événements eux-mêmes n'est pas à toute épreuve.
Par exemple, disons que vous avez découvert qu'un utilisateur a émis un réel mousemove (pas le faux à partir d'événements tactiles, voir http://www.html5rocks.com/en/mobile/touchandmouse/).
Alors quoi?
Vous activer le survol des styles? Vous ajoutez plus de boutons?
De toute façon vous pouvez augmenter le temps de verre parce que vous devez attendre pour un événement à feu.
Mais alors ce qui arrive quand votre noble utilisateur décide veut débrancher sa souris et aller tactile.. ne vous attendez pour lui de toucher votre maintenant entassés à l'interface, puis de le changer juste après avoir fait l'effort de localiser votre maintenant encombré d'INTERFACE utilisateur?
En forme de balle, citant stucox à https://github.com/Modernizr/Modernizr/issues/869#issuecomment-15264101
Un côté: le navigateur NE sait quand un utilisateur connecte une souris/se connecte à un clavier, mais ne pas l'exposer à de JavaScript.. dang!
Cela devrait vous conduire à la suivante:
L'idée de l'amélioration progressive, s'applique très bien ici. Construire une expérience qui fonctionne quel que soit le contexte de l'utilisateur. Ensuite, faire des hypothèses basées sur les fonctionnalités du navigateur/media queries pour ajouter des fonctionnalités qui seront relative dans l'hypothèse d'un contexte. La présence d'une souris est juste un de la multitude de façons dont les différents utilisateurs sur les différents appareils de l'expérience de votre site web. Créer quelque chose de mérite à son noyau, et ne vous inquiétez pas trop à propos de la façon dont les gens cliquent sur les boutons.
:hover
éléments et des choses comme ça) lorsque l'utilisateur de passer de la souris au toucher. Il semble peu probable que l'utilisateur est actuellement à l'aide de la souris + touche à l'exact même temps (je veux dire comoonn c'est comme avoir 2 souris connectés à l'ordinateur même hahaha)Comment à l'écoute pour un événement mousemove sur le document. Ensuite, jusqu'à entendre cet événement vous supposez que l'appareil est tactile ou clavier uniquement.
(Où
listen
etunlisten
délégué àaddEventListener
ouattachEvent
selon le cas).J'espère que cela ne le conduise pas à trop de visual jank, il serait sucer si vous avez besoin massif de re-mises en page basées sur le mode...
window.document.body.addEventListener('mousemove', function (e) { e.preventDefault(); e.stopImmediatePropagation(); }, true);
@Wyatt réponse est grande et nous donne beaucoup à penser.
Sur mon cas, j'ai choisi d'écouter pour la première interaction, à seulement ensuite définir un comportement. Donc, même si l'utilisateur a une souris, je vais le traiter comme le toucher de l'appareil si la première interaction a une touche.
Compte tenu de la compte tenu de l'ordre dans lequel les événements sont traités:
On peut supposer que si la souris événement est déclenché avant de le toucher, c'est un véritable événement de souris, pas un émulé un. Exemple (à l'aide de jQuery):
Qui a fonctionné pour moi
À partir de 2018, il y a un bon et fiable pour détecter si le navigateur a une souris (ou autre périphérique d'entrée): CSS4 interaction avec les médias fonctionnalités qui sont désormais pris en charge par presque n'importe quel navigateur moderne (sauf IE 11 et spécial les navigateurs mobiles).
W3C:
Voir les options suivantes:
Requêtes de média peut également être utilisé en JS:
Connexes:
Officiel du projet de travail: https://drafts.csswg.org/mediaqueries/#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 unis
Il n'est possible de détecter si un navigateur tactile capable. Il n'y a aucun moyen de savoir si c'est réellement un écran tactile ou une souris connectée.
On peut privilégier l'emploi bien que par l'écoute de l'événement tactile à la place de la souris de l'événement si la capacité tactile est détecté.
Pour détecter les capacités tactiles de la croix-navigateur:
Alors on peut l'utiliser pour vérifier:
ou pour choisir les événements à écouter, soit:
ou de l'utilisation des approches distinctes pour le tactile et non tactile:
Pour la souris, on peut seulement détecter si la souris est utilisée, pas si elle existe ou pas. On peut mettre en place un indicateur global pour indiquer que la souris a été détectée par l'utilisation (similaire à une réponse, mais simplifié un peu):
(on ne peut pas inclure
mouseup
oumousedown
que ces événements peuvent également être déclenchées par le toucher)Navigateurs permet de restreindre l'accès de bas niveau du système d'Api qui est nécessaire pour être en mesure de détecter des fonctionnalités telles que les capacités matérielles du système, il est utilisé sur.
Il y a la possibilité de peut-être écrire un plugin/extension de l'accès à ces mais par l'intermédiaire de JavaScript et DOM telles que la détection est limitée à cette fin, et il faudrait écrire un plugin spécifique pour les différentes plateformes de système d'exploitation.
Donc, en conclusion: une telle détection ne peut être estimée que par une "bonne estimation".
Quand Les Media Queries Niveau 4 est disponible dans les navigateurs, nous serons en mesure d'utiliser le "pointeur" et "hover" requêtes à détecter les périphériques avec une souris.
Si l'on veut vraiment communiquer que des informations sur Javascript, nous pourrions utiliser un CSS requête pour définir des styles spécifiques selon le type d'appareil, puis utilisez
getComputedStyle
en Javascript pour lire ce style, et de dériver de l'appareil d'origine type de il.Mais une souris peut être connecté ou débranché à tout moment, l'utilisateur peut vouloir basculer entre les toucher et de la souris. Donc, nous pouvons avoir besoin de détecter ce changement, et d'offrir à l'interface de changement ou de le faire automatiquement.
any-pointer
etany-hover
vous permettra d'étudier toutes les lois des capacités des appareils. Agréable de recevoir un coup d'oeil à la façon dont nous pourrions résoudre ce problème à l'avenir! 🙂Puisque vous avez l'intention d'offrir un moyen de basculer entre les interfaces de toute façon, serait-il possible de simplement demander à l'utilisateur de cliquer sur un lien ou un bouton "entrer" dans la version de l'application? Alors on pourrait se souvenir de leurs préférences pour de futures visites. Ce n'est pas de la haute technologie, mais c'est fiable à 100%: -)
@SamuelRossille Pas les navigateurs que je suis au courant exposent l'existence (ou l'absence) d'une souris, malheureusement.
Donc, avec cela étant dit, nous avons juste à essayer de le faire le mieux que nous pouvons avec notre option... événements. Je sais que c'est pas exactement ce que vous cherchez... ont convenu qu'il est actuellement loin d'être idéal.
Nous pouvons faire de notre mieux pour déterminer si un utilisateur est à l'aide d'une souris ou de toucher à un moment donné. Voici un rapide exemple à l'aide de jQuery & knock-out:
Vous pouvez maintenant bind/abonnez-vous à usingMouse() & usingTouch() et/ou le style de votre interface avec le corps.souris classe. Le d'interface basculer en arrière dès que le curseur de la souris est détectée et sur les évènements touchstart.
J'espère que nous aurons de meilleures options à partir du navigateur vendeurs bientôt.
Tera-WURFL peux vous dire que les capacités de l'appareil qui est de la visite de votre site en comparant le navigateur signature contre sa base de données. Lui donner un look, c'est gratuit!
Pourquoi ne pas vous venez de détecter si elle a la capacité de sentir les touches et/ou de réagir aux mouvements de la souris?
has_touch = 'ontouchstart' in window
suffira, et ainsi de suite.'onmousemove' in window
esttrue
dans safari iPad....Cela a fonctionné pour moi dans une situation similaire. Fondamentalement, supposons que l'utilisateur ne dispose pas d'une souris jusqu'à ce que vous voyez une courte série consécutive de mousemoves, sans l'intervention de l'mousedowns ou mouseups. Pas très élégant, mais il fonctionne.
le principal problème que je vois ici, c'est que la plupart des appareils tactiles feu un événement de souris avec la touche correspondant à un (évènements touchstart -> mousedown, touchmove -> mousemove, etc).
Pour le clavier seuls, enfin pour les modernes, ils ont un générique du navigateur de sorte que vous pouvez même pas détecter la présence de la classe MouseEvent.
Le moins pénible solution ici serait, à mon avis, pour afficher un menu au lancement (avec " alt " de gestion pour le clavier seuls les utilisateurs) et peut-être stocker le choix avec localStorage/cookies/server-side ou d'autre pour garder la salme choix la prochaine fois que le visiteur venu.
Ont un coup d'oeil à modenizr une de ses particularités est de toucher
http://modernizr.com/docs/#features-misc
Alors que je n'ai pas testé pleinement il semble fonctionner très bien
Aussi c'est lié à partir de la page modernizr
http://www.html5rocks.com/en/mobile/touchandmouse/
Comme d'autres l'ont souligné, définitivement détecter 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 le faire de manière fiable avec une valeur booléenne true ou false, au moins sur un document de l'échelle.
Toucher les événements et les événements de la souris sont exclusifs. Si cela peut aider dans une certaine mesure d'effectuer différentes actions. Le problème est que les événements tactiles sont plus proches de la souris vers le haut/vers le bas/déplacer des événements, et aussi déclencher un événement de clic.
De votre question, vous dites que vous voulez avoir une info pour afficher l'aperçu. Au-delà de ce que je ne connais pas d'autres détails au sujet de votre interface. Je suis en supposant qu'avec l'absence de souris, vous voulez un robinet pour obtenir un aperçu, tout en un clic n'a une action différente en raison de la hover aperçu.
Si c'est le cas, vous pouvez prendre un peu paresseux approche de la détection:
Un événement onclick sera toujours précédée par un événement onmouseover avec une souris. Alors, notez que la souris est au-dessus de l'élément qui a été cliqué.
Vous pouvez le faire avec un document à l'échelle de l'événement onmousemove. Vous pouvez utiliser
event.target
pour enregistrer l'élément de la souris est résidant sur. Ensuite, à l'intérieur de votre événement onclick, vous pouvez vérifier pour voir si la souris est en fait plus de l'élément cliqué (ou un enfant de l'élément).À partir de là, vous pouvez choisir soit de s'appuyer sur l'événement click pour les deux et prendre une A ou B de l'action en fonction du résultat. Le B d'action pourrait être rien de si certains appareils tactiles n'émettent pas d'un événement de clic (au lieu de cela vous aurait à s'appuyer sur ontouch* événements).
Je ne pense pas qu'il est possible d'identifier uniquement les commandes tactiles de l'appareil (à ma connaissance bien sûr). La question principale est celle de tous les souris et le clavier événements sont déclenchés par les appareils tactiles trop.
Voir l'exemple suivant, les deux alertes retourner vrai pour les appareils tactiles.
true
pour'onmousedown' in window
La meilleure idée à mon avis est le
mousemove
auditeur (actuellement la première réponse). Je crois que cette méthode doit être modifié un peu. Il est vrai que toucher les navigateurs basés sur émuler même de l'événement mousemove, comme vous pouvez le voir dans cet iOS discussion, donc on devrait être un peu prudent.Ça a du sens tactile, les navigateurs ne peuvent émuler cet événement lorsque l'utilisateur appuie sur l'écran (le doigt de l'utilisateur est en panne). Cela signifie que nous devons ajouter un test lors de notre gestionnaire mousemove pour voir quel bouton de la souris est enfoncée (le cas échéant) au cours de l'événement. Si aucun bouton de la souris est enfoncé, on peut supposer une vraie souris est présente. Si un bouton de la souris est enfoncé, le test ne sont pas concluantes.
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 éteint au cours d'un événement mousemove est de les écouter pour les 3 événements dans le document de niveau: mousemove, mousedown et mouseup. Le haut et le bas ne mondial indicateur booléen. Le déménagement permettra de réaliser le test. Si vous avez un déménagement et le booléen est faux, on peut supposer une souris est présente. Voir la question exacte des exemples de code.
Un commentaire final.. Ce test n'est pas idéal, car il ne peut pas être effectuée dans les temps de chargement. Donc, je voudrais utiliser une amélioration progressive de la méthode comme suggéré précédemment. Par défaut, afficher une version qui ne prend pas en charge la souris spécifiques passez de l'interface. Si une souris est découvert, l'activation de ce mode en cours d'exécution en utilisant JS. Ce doit apparaître de la façon la plus transparente possible pour l'utilisateur.
Afin de soutenir les changements dans la configuration de l'utilisateur (c'est à dire de la souris a été déconnecté), vous pouvez périodiquement re-test. Bien que je crois qu'il vaudra mieux dans ce cas pour simplement informer l'utilisateur sur les 2 modes et permettent aux utilisateurs de basculer manuellement entre eux (un peu comme le mobile/desktop choix qui peut toujours être inversé).
Couru quelques tests sur différents PC, Linux, iPhone, les téléphones Android et les onglets. Bizarre qu'il n'est pas facile à l'épreuve des balles solution. Le problème se pose lorsque certains qui ont Touch et pas de souris toujours présent Touch et les événements de la Souris à l'application. Depuis voulez prendre en charge la souris seulement et uniquement tactiles cas, à traiter à la fois, mais cela provoque double occurrences d'interactions de l'utilisateur. Si peut savoir de la souris n'est pas présent sur l'appareil, puis peut savoir à ignorer faux/insérés les événements de la souris. Essayé paramètre d'indicateur de si MouseMove est rencontré, mais certains navigateurs jeter faux MouseMove ainsi que MouseUp et MouseDown. Essayé de l'examen des horodateurs, mais pensé que c'était trop risqué. Bottom line: j'ai trouvé les navigateurs qui a créé le faux événements de souris toujours inséré un seul MouseMove juste avant l'insertion des MouseDown. Dans 99,99% de mon cas, lors de l'exécution sur un système qui a une vraie souris, il y a de multiples consécutifs MouseMove événements - au moins deux. Donc, garder une trace de savoir si le système de deux rencontres consécutives MouseMove événements et de déclarer, il n'y a pas de souris à présent si cette condition n'est jamais remplie. C'est sans doute trop simple, mais son travail sur toutes mes configurations de test. Pense que je vais rester avec elle jusqu'à ce que je trouve une meilleure solution. - Jim W
Une solution simple en jQuery pour détecter l'usage de la souris, ce qui résout le problème où les appareils mobiles aussi trigger 'mousemove' événement. Il suffit d'ajouter un écouteur d'évènements touchstart pour supprimer l'événement mousemove de l'auditeur, de sorte qu'elle ne soit pas déclenchée sur la touche.
Bien sûr, le dispositif pourrait encore être tactile ET la souris, mais la ci-dessus sera la garantie d'une vraie souris a été utilisé.
Viens de trouver une solution qui je pense est tout à fait élégant.
J'ai rencontré le même problème, où une touche unique a également été enregistrée comme un clic.
Après j'ai lu les commentaires de haut voté réponses, je suis venu avec ma propre solution:
JS:
CSS:
HTML:
Le seul problème que j'ai trouvé est que vous devez être en mesure de faire défiler, de détecter correctement un événement tactile. un seul onglet(touch) pourrait créer des problèmes.
J'ai passé des heures à essayer de comprendre ce problème pour mon app Phonegap et je suis venu avec ce hack. Il génère une console d'avertissement si l'événement a déclenché une "passive" de l'événement, le sens qu'il n'a pas d'actionner une modification, mais il fonctionne! J'aimerais des idées pour améliorer ou à une meilleure méthode. Mais cela permet effectivement à mon utilisation de $.touch() universellement.
JS:
HTML:
Je recommanderais fortement à l'encontre de cette approche. Envisager l'écran tactile, ordinateur de bureau de taille des appareils, et vous avez un ensemble différent de problèmes à résoudre.
Veuillez vous rendre votre application utilisable sans souris (c'est à dire pas de hover aperçu).
Voudrais vous recommandons d'un script qui m'a aidé:
J'avais lu et essayé tout ce qui est suggéré, sans suffisamment de résultats.
Ensuite, j'ai étudié un peu plus, et trouvé ce code - device.js
J'utilise dans mon site du client, de détecter la souris existence:
(
<html>
devrait avoirdesktop
classe) et il semble assez bon, et pourtouch
soutien, je viens de faire la vérification régulière'ontouchend' in document
et utiliser l'information provenant de deux détections qu'une chose dont j'ai besoin.Il est généralement une meilleure idée de détecter si la fonction mouseover est pris en charge plutôt que de les détecter l'OS/type de navigateur. Vous pouvez le faire simplement par ce qui suit:
Assurez-vous que vous ne pas procédez de la manière suivante:
Ce dernier serait en fait l'appel à la méthode, plutôt que de vérifier son existence.
Vous pouvez en lire plus ici:
http://www.quirksmode.org/js/support.html