181 votes

Détecter que le navigateur n’a aucune souris et est tactile seulement

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.

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

77voto

Wyatt Points 1461

Le principal problème, c'est que vous avez la suite de différentes classes de périphériques/cas d'utilisation:

  1. De la souris et keyboad (bureau)
  2. Seule touche (téléphone/tablette)
  3. La souris, le clavier, et le toucher (touch ordinateurs portables)
  4. Tactile et le clavier (clavier bluetooth sur la tablette)
  5. La souris seulement (Désactivé utilisateur/de la navigation de préférence)
  6. Seul clavier (Désactivé utilisateur/de la navigation de préférence)
  7. Toucher et de la souris (c'est à dire passez des événements à partir de Galaxy Note 2 pen)

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?

Dans un style télégraphique, citant stucox à https://github.com/Modernizr/Modernizr/issues/869#issuecomment-15264101

  • Nous voulons détecter la présence d'une souris
  • Ae probablement ne peuvent pas le détecter avant qu'un événement est déclenché
  • En tant que tel, ce que nous cherchons à détecter si une souris a été utilisé dans cette session, il ne sera pas immédiatement à partir de la page de chargement
  • Nous avons probablement aussi ne peut pas détecter qu'il n'y a pas une souris serait indéfini jusqu'à ce qu'vrai (je pense que cela fait plus de sens que de fixer elle est fausse jusqu'à preuve)
  • Et nous ne pouvons pas détecter si une souris est déconnecté de la mi-session - ça va être impossible à distinguer de l'utilisateur juste de donner à leurs souris

D'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:

Le suivi de la capacité actuelle d'un utilisateur donné est complexe, incertain et douteux mérite

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.

65voto

Dan Points 551

Qu’en est-il à l’écoute pour un événement mousemove sur le document. Puis jusqu'à ce que vous entendiez cet événement vous supposez que l’appareil est tactile ou clavier seulement.

(Où et déléguer à ou selon le cas.)

J’espère que cela ne serait pas entraîner trop visuel jank, il craint si vous avez besoin massives redispositions selon le mode...

24voto

Hugo Silva Points 868

@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 l' ordre dans lequel les événements sont traités:

  1. évènements touchstart
  2. touchmove
  3. touchend
  4. passage de la souris
  5. mousemove
  6. mousedown
  7. mouseup
  8. cliquez sur

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é. Exemple (à l'aide de jQuery):

$(document).ready(function() {
    var $body = $('body');
    var detectMouse = function(e){
        if (e.type === 'mousemove') {
            alert('Mouse interaction!');
        }
        else if (e.type === 'touchstart') {
            alert('Touch interaction!');
        }
        // remove event bindings, so it only runs once
        $body.off('mousemove touchstart', detectMouse);
    }
    // attach both events to body
    $body.on('mousemove touchstart', detectMouse);
});

Cela a fonctionné pour moi

13voto

Ken Fyrstenberg Points 38115

Il est seulement 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:

function hasTouch() {
    return (('ontouchstart' in window) ||       // html5 browsers
            (navigator.maxTouchPoints > 0) ||   // future IE
            (navigator.msMaxTouchPoints > 0));  // current IE10
}

Ensuite, on peut l'utiliser pour vérifier:

if (!hasTouch()) alert('Sorry, need touch!);

ou pour choisir les événements à écouter, soit:

var eventName = hasTouch() ? 'touchend' : 'click';
someElement.addEventListener(eventName , handlerFunction, false);

ou de l'utilisation des approches distinctes pour le tactile et non tactile:

if (hasTouch() === true) {
    someElement.addEventListener('touchend' , touchHandler, false);

} else {
    someElement.addEventListener('click' , mouseHandler, false);

}
function touchHandler(e) {
    /// stop event somehow
    e.stopPropagation();
    e.preventDefault();
    window.event.cancelBubble = true;
    // ...
    return false; // :-)
}
function mouseHandler(e) {
    // sorry, touch only - or - do something useful and non-restrictive for user
}

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):

var hasMouse = false;

window.onmousemove = function() {
    hasMouse = true;
}

(on ne peut pas inclure mouseup ou mousedown que ces événements peuvent également être déclenchées par le toucher)

Les navigateurs restreint 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".

7voto

Brandan Points 8311

Puisque vous avez l’intention d’offrir la possibilité de basculer entre les interfaces de toute façon, il serait possible de simplement demander à l’utilisateur de cliquer sur un lien ou un bouton « entrer » la version correcte de l’application ? Ensuite, il pourrait retenir leur préférence pour de futures visites. Il n’est pas haute technologie, mais il est 100 % fiable  :-)

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X