web-dev-qa-db-fra.com

Détecter que le navigateur n'a pas de souris et est tactile

Je développe une application Web (et non un site Web contenant des pages de texte intéressant) avec une interface tactile très différente (votre doigt masque l’écran lorsque vous cliquez) et une souris (qui repose beaucoup sur l’aperçu survol) . que mon utilisateur n'a pas de souris pour lui présenter la bonne interface? Je prévois de laisser un commutateur pour les personnes ayant à la fois une souris et une touche (comme certains ordinateurs portables). 

La fonctionnalité d'événement tactile dans le navigateur ne signifie pas réellement que l'utilisateur utilise un périphérique tactile (par exemple, Modernizr ne le coupe pas). Le code qui répond correctement à la question doit renvoyer false si le périphérique est équipé d'une souris, true sinon. Pour les appareils avec souris et écran tactile, la valeur false doit être renvoyée (pas uniquement tactile).

En passant, mon interface tactile peut également convenir aux périphériques uniquement à clavier, c'est donc plutôt le manque de souris que je cherche à détecter.

Pour clarifier le besoin, voici l’API que je souhaite 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);
135
nraynaud

Le problème principal est que vous avez les différentes classes de périphériques/cas d'utilisation suivantes:

  1. Souris et clavier (bureau)
  2. Tactile uniquement (téléphone/tablette)
  3. Souris, clavier et écran tactile (ordinateurs portables tactiles)
  4. Toucher et clavier (clavier Bluetooth sur tablette)
  5. Souris uniquement (préférence utilisateur/navigation désactivé)
  6. Clavier uniquement (préférence utilisateur/navigation désactivé)
  7. Toucher et souris (événements de survol du stylet Galaxy Note 2)

Le pire, c’est que l’on peut passer d’une classe à l’autre (plug-in d’une souris, se connecter au clavier), ou qu’un utilisateur peut apparaître comme étant sur un ordinateur portable normal jusqu’à ce qu’ils touchent 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 que cela est quelque peu incohérent). De plus, à moins que vous ne suiviez un événement très spécifique ou n'essayiez que d'éliminer 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 déplacement de souris (et non le faux des événements tactiles, voir http://www.html5rocks.com/fr/mobile/touchandmouse/ ).

Alors quoi?

Vous activez les styles de survol? Vous ajoutez plus de boutons?

De toute façon, 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 se toucher complètement? Attendez-vous qu'il touche votre interface désormais pleine à craquer, puis changez-la juste après qu'il ait fait l'effort de localiser votre interface maintenant bondée?

Sous forme de puce, citant stucox à https://github.com/Modernizr/Modernizr/issues/869#issuecomment-15264101

  • Nous voulons détecter la présence d'une souris
  • Ae ne peut probablement pas détecter avant qu'un événement ne soit déclenché
  • En tant que tel, ce que nous détectons, c'est si une souris a été utilisée dans cette session - ce ne sera pas immédiatement du chargement de la page.
  • Nous ne pouvons probablement pas non plus détecter qu’il n’existe pas de souris - elle ne serait pas définie tant que ce n’est pas vrai (je pense que cela a plus de sens que de définir Que faux jusqu’à preuve du contraire)
  • Et nous ne pourrons probablement pas détecter si une souris est déconnectée en cours de session - cela sera impossible à distinguer de l'utilisateur qui abandonne simplement son Souris

Un côté: 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:

Suivre les capacités actuelles d'un utilisateur donné est complexe, peu fiable et d'un mérite douteux

L'idée d'amélioration progressive s'applique assez bien ici, cependant. Construisez une expérience qui fonctionne bien, peu importe le contexte de l'utilisateur. Ensuite, formulez des hypothèses en fonction des fonctionnalités du navigateur/des requêtes de média pour ajouter une fonctionnalité qui sera relative dans le contexte supposé. La présence d'une souris est l'une des multiples façons dont différents utilisateurs sur différents appareils voient votre site Web. Créez quelque chose de mérite à son noyau et ne vous inquiétez pas trop de la façon dont les gens cliquent sur les boutons.

56
Wyatt

Pourquoi ne pas écouter un événement de souris sur le document? Ensuite, jusqu'à ce que vous entendiez cet événement, vous supposez que l'appareil est tactile ou clavier uniquement.

var mouseDetected = false;
function onMouseMove(e) {
  unlisten('mousemove', onMouseMove, false);
  mouseDetected = true;
  // initializeMouseBehavior();
}
listen('mousemove', onMouseMove, false);

(Où listen et unlisten déléguer à addEventListener ou attachEvent selon le cas.)

Espérons que cela ne conduirait pas à trop de jank visuel, ce serait nul si vous avez besoin de remodeler massivement en fonction du mode ...

56
Dan

La réponse de @ Wyatt est excellente et nous donne beaucoup de matière à réflexion.

Sur 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 tactile. 

Considérant l'ordre l'ordre donné dans lequel les événements sont traités :

  1. touchstart
  2. toucher
  3. toucher
  4. passer la souris
  5. déplacer la souris
  6. souris vers le bas
  7. mouseup
  8. cliquez sur

Nous pouvons supposer que si un événement de souris est déclenché avant le toucher, il s'agit d'un véritable événement de souris, et non d'un émulé. Exemple (en utilisant jQuery):

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

Cela a fonctionné pour moi

23
Hugo Silva

Il est seulement possible de détecter si un navigateur est tactile capable. Il n'y a aucun moyen de savoir s'il dispose d'un écran tactile ou d'une souris connectée.

On peut cependant prioriser l'utilisation en écoutant un événement tactile au lieu d'un événement avec la souris si la capacité tactile est détectée.

Pour détecter la fonctionnalité tactile sur plusieurs navigateurs:

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

Ensuite, on peut utiliser ceci pour vérifier:

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

ou choisir quel événement écouter, soit:

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

ou utilisez des approches distinctes pour le toucher par rapport au non-toucher:

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

var hasMouse = false;

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

(on ne peut pas inclure mouseup ou mousedown car ces événements peuvent également être déclenchés au toucher)

Les navigateurs limitent l'accès aux API de système de bas niveau, nécessaires pour détecter des fonctionnalités telles que les capacités matérielles du système sur lequel il est utilisé.

Il est possible d’écrire un plugin/une 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 plateformes de système d’exploitation.

Donc, en conclusion: une telle détection ne peut être estimée que par une "bonne supposition".

9
user1693593

Quand Media Queries Level 4 est disponible dans les navigateurs, nous pourrons utiliser les requêtes "pointeur" et "survol" pour détecter les périphériques à l'aide d'une souris.

Si nous souhaitons réellement 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éduire le type d'appareil d'origine.

Mais une souris peut être connected ou unplugged à tout moment, et l'utilisateur peut vouloir basculer entre le toucher et la souris. Il se peut donc que nous devions détecter ce changement et nous proposer de changer d’interface ou de le faire automatiquement.

7
joeytwiddle

À partir de 2018, il existe un moyen fiable de détecter si un navigateur est équipé d'une souris (ou d'un périphérique de saisie similaire): fonctionnalités d'interaction média CSS4 déjà prises en charge par les navigateurs les plus modernes bientôt). 

W3C:

La fonctionnalité de pointeur est utilisée pour interroger la présence et la précision d'un périphérique de pointage tel qu'une souris.

Voir les options suivantes:

    /* The primary input mechanism of the device includes a 
pointing device of limited accuracy. */
    @media (pointer: coarse) { ... }

    /* The primary input mechanism of the device 
includes an accurate pointing device. */
    @media (pointer: fine) { ... }

    /* The primary input mechanism of the 
device does not include a pointing device. */
    @media (pointer: none) { ... }

    /* Primary input mechanism system can 
       hover over elements with ease */
    @media (hover: hover) { ... }

    /* Primary input mechanism cannot hover 
       at all or cannot conveniently hover 
       (e.g., many mobile devices emulate hovering
       when the user performs an inconvenient long tap), 
       or there is no primary pointing input mechanism */
    @media (hover: none) { ... }

    /* One or more available input mechanism(s) 
       can hover over elements with ease */
    @media (any-hover: hover) { ... }


    /* One or more available input mechanism(s) cannot 
       hover (or there are no pointing input mechanisms) */
    @media (any-hover: none) { ... }

Les requêtes multimédia peuvent également être utilisées dans JS:

if(window.matchMedia("(any-hover: none)").matches) {
    // do sth
}

En relation:

https://drafts.csswg.org/mediaqueries/#mf-interaction

Détecte si un périphérique client prend en charge: survol et: états de focus

6
Blackbam

Puisque vous envisagez de toute façon de proposer un moyen de basculer entre les interfaces, serait-il possible de demander simplement à l'utilisateur de cliquer sur un lien ou un bouton pour "entrer" la version correcte de l'application? Ensuite, vous pouvez vous rappeler leur préférence pour les visites futures. Ce n'est pas de la haute technologie, mais c'est fiable à 100% :-)

6
Brandan

@SamuelRossille Aucun navigateur que je sache n'expose l'existence d'une souris (ou son absence), malheureusement.

Cela 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 ... convenez que c’est loin d’être idéal.

Nous pouvons faire de notre mieux pour déterminer si un utilisateur utilise une souris ou une touche au même moment. Voici un exemple rapide et sale utilisant jQuery & Knockout:

//namespace
window.ns = {};

// for starters, we'll briefly assume if touch exists, they are using it - default behavior
ns.usingTouch = ko.observable(Modernizr.touch); //using Modernizr here for brevity.  Substitute any touch detection method you desire

// now, let's sort out the mouse
ns.usingMouse = ko.computed(function () {
    //touch
    if (ns.usingTouch()) {
        //first, kill the base mousemove event
        //I really wish browsers would stop trying to handle this within touch events in the first place
        window.document.body.addEventListener('mousemove', function (e) {
            e.preventDefault();
            e.stopImmediatePropagation();
        }, true);

        //remove mouse class from body
        $('body').removeClass("mouse");

        //switch off touch listener
        $(document).off(".ns-touch");

        // switch on a mouse listener
        $(document).on('mousemove.ns-mouse', function (e) {
            if (Math.abs(window.lastX - e.clientX) > 0 || window.lastY !== e.clientY) {
                ns.usingTouch(false);  //this will trigger re-evaluation of ns.usingMouse() and result in ns.usingMouse() === true
            }
        });

        return false;
    }
    //mouse
    else {
        //add mouse class to body for styling
        $('body').addClass("mouse");

        //switch off mouse listener
        $(document).off(".ns-mouse");

        //switch on a touch listener
        $(document).on('touchstart.ns-touch', function () { ns.usingTouch(true) });

        return true;
    }
});

//tests:
//ns.usingMouse()
//$('body').hasClass('mouse');

Vous pouvez maintenant vous lier/vous abonner à usingMouse () & usingTouch () et/ou à votre interface avec la classe body.mouse . L'interface bascule dès qu'un curseur de souris est détecté et au toucher.

Espérons que les éditeurs de navigateurs auront bientôt de meilleures options.

4
daredev

Pourquoi ne détectez-vous pas simplement s'il est capable de détecter les contacts et/ou de réagir aux mouvements de la souris?

// This will also return false on
// touch-enabled browsers like Chrome
function has_touch() {
  return !!('ontouchstart' in window);
}

function has_mouse() {
  return !!('onmousemove' in window);
}
2
iblue

Cela a fonctionné pour moi dans une situation similaire. Fondamentalement, supposons que l'utilisateur ne possède pas de souris jusqu'à ce que vous voyiez une courte série de déplacements de souris consécutifs, sans interventions de souris ou de souris. Pas très élégant, mais ça marche.

var mousedown = false;
var mousemovecount = 0;
function onMouseDown(e){
    mousemovecount = 0;
    mousedown = true;
}
function onMouseUp(e){
    mousedown = false;
    mousemovecount = 0;
}
function onMouseMove(e) {
    if(!mousedown) {
        mousemovecount++;
        if(mousemovecount > 5){
            window.removeEventListener('mousemove', onMouseMove, false);
            console.log("mouse moved");
            $('body').addClass('has-mouse');
        }
    } else {
        mousemovecount = 0;
    }
}
window.addEventListener('mousemove', onMouseMove, false);
window.addEventListener('mousedown', onMouseDown, false);
window.addEventListener('mouseup', onMouseUp, false);
2

Tera-WURFL peut vous indiquer les capacités du périphérique qui visite votre site en comparant la signature du navigateur à sa base de données. Donnez-lui un coup d'oeil, c'est gratuit!

2
Gigi

le principal problème que je vois ici est que la plupart des appareils tactiles déclenchent un événement de souris avec l'événement tactile correspondant (touchstart -> mousedown, touchmove -> mousemove, etc.). Pour les seuls claviers, enfin pour les plus modernes, ils ont un navigateur générique, 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 la gestion 'alt' pour les utilisateurs uniquement au clavier) et peut-être de stocker le choix avec localStorage/cookies/serverside ou encore de conserver le choix de salme le prochain le temps que le visiteur vienne.

0
Ernoriel

La meilleure idée à mon avis est l'auditeur mousemove (actuellement la meilleure réponse). Je crois que cette méthode doit être légèrement modifiée. Il est vrai que les navigateurs tactiles imitent même l'événement mousemove, comme vous pouvez le constater dans cette discussion sur iOS , nous devons donc être un peu prudents.

Il est logique que les navigateurs tactiles émulent cet événement uniquement lorsque l'utilisateur appuie sur l'écran (le doigt de l'utilisateur est enfoncé). Cela signifie que nous devrions ajouter un test lors de notre gestionnaire de déplacement de souris 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 reste non concluant.

Alors, comment cela serait-il mis en œuvre? Cette question montre que la méthode la plus fiable pour déterminer quel bouton de la souris est enfoncé pendant un déplacement de souris consiste à écouter 3 événements dans le niveau du document: déplacement de souris, déplacement de souris et souris vers le haut. Le haut et le bas ne définiront qu'un drapeau booléen global. Le déménagement effectuera le test. Si vous avez un coup et que le booléen est faux, nous pouvons supposer qu'une souris est présente. Voir la question pour des exemples de code exact.

Un dernier commentaire .. Ce test n'est pas idéal car il ne peut pas être effectué dans le temps de chargement. Par conséquent, j'utiliserais une méthode d'amélioration progressive comme suggéré précédemment. Par défaut, affichez 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 lors de l'exécution à l'aide de JS. Cela devrait apparaître aussi transparent que possible pour l'utilisateur.

Afin de prendre en charge les modifications de la configuration de l'utilisateur (la souris a été déconnectée), vous pouvez périodiquement tester à nouveau. Bien que je pense qu’il sera préférable dans ce cas de simplement informer l’utilisateur des 2 modes et de les laisser basculer manuellement entre eux (un peu comme le choix mobile/ordinateur de bureau qui peut toujours être inversé).

0
talkol

Une solution simple dans jQuery pour détecter l'utilisation de la souris, ce qui résout le problème selon lequel les appareils mobiles déclenchent également un événement 'mousemove'. Ajoutez simplement un écouteur Touchstart pour supprimer l’auditeur mousemove, afin qu’il ne soit pas déclenché au toucher.

$('body').one('touchstart.test', function(e) {
  // Remove the mousemove listener for touch devices
  $('body').off('mousemove.test');
}).one('mousemove.test', function(e) {
  // MOUSE!
});

Bien sûr, le périphérique pourrait toujours être tactile ET souris, mais ce qui précède garantit l'utilisation d'une vraie souris.

0
suncat100

J'ai passé des heures à résoudre ce problème pour mon application Phonegap et j'ai trouvé ce hack. Il génère un avertissement de la console si l'événement déclenché est un événement "passif", ce qui signifie qu'il n'engendre aucun changement, mais cela fonctionne! Je serais intéressé par des idées pour améliorer ou une meilleure méthode. Mais ceci me permet effectivement d’utiliser $ .touch () universellement.

$(document).ready(function(){
  $("#aButton").touch(function(origElement, origEvent){
    console.log('Original target ID: ' + $(origEvent.target).attr('id'));
  });
});

$.fn.touch = function (callback) {
    var touch = false;
    $(this).on("click", function(e){
        if (!touch)
        {
            console.log("I click!");
            let callbackReal = callback.bind(this);
            callbackReal(this, e);
        }else{
            touch = true;
        }
        touch = false;
    });
    $(this).on("touchstart", function(e){
        if (typeof e.touches != typeof undefined)
        {
            e.preventDefault();
            touch = true;
            console.log("I touch!");
            let callbackReal = callback.bind(this);
            callbackReal(this, e);
        }
    });
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>

<button id="aButton">A Button</button>

0
Jay

Je ne pense pas qu'il soit possible d'identifier un périphérique tactile (à ma connaissance bien sûr). Le problème principal est que tous les événements de souris et de clavier sont déclenchés également par les périphériques tactiles .Voir l'exemple suivant, les deux alertes retournent la valeur true pour les périphériques tactiles.

function is_touch_present() {
  return ('ontouchstart' in window) || ('onmsgesturechange' in window);
}

function is_mouse_present() {
  return (('onmousedown' in window) && ('onmouseup' in window) && ('onmousemove' in window) && ('onclick' in window) && ('ondblclick' in window) && ('onmousemove' in window) && ('onmouseover' in window) && ('onmouseout' in window) && ('oncontextmenu' in window));
}

alert("Touch Present: " + is_touch_present());
alert("Mouse Present: " + is_mouse_present());
0
Bikas

Je suis tombé sur le même problème, où une simple touche était également enregistrée en tant que clic . Après avoir lu les commentaires des réponses les plus votées, j'ai proposé ma propre solution:

var body = document.getElementsByTagName('body')[0];
var mouseCount = 0;

// start in an undefined state 
// (i use this to blend in elements once we decide what input is used)
var interactionMode = 'undefined';


var registerMouse = function() {
  // count up mouseCount every time, the mousemove event is triggered
  mouseCount++;

  // but dont set it instantly. 
  // instead wait 20 miliseconds (seems to be a good value for multiple move actions), 
  // if another mousemove event accoures switch to mouse as interaction 
  setTimeout(function() {
    // a touch event triggers also exactly 1 mouse move event.
    // So only if mouseCount is higher than 1 we are really moving the cursor by mouse.
    if (mouseCount > 1) {
      body.removeEventListener('mousemove', registerMouse);
      body.removeEventListener('touchend', registerTouch);

      interactionMode = 'mouse';
      console.log('now mousing');
      listenTouch();
    }

    // set the counter to zero again
    mouseCount = 0;
  }, 20);
};

var registerTouch = function() {
  body.removeEventListener('mousemove', registerMouse);
  body.removeEventListener('touchend', registerTouch);

  interactionMode = 'touch';
  console.log('now touching');
  mouseCount = 0;

  listenMouse();
};

var listenMouse = function() {
  body.addEventListener("mousemove", registerMouse);
};
var listenTouch = function() {
  body.addEventListener("touchend", registerTouch);
};

listenMouse();
listenTouch();

// after one second without input, assume, that we are touching
// could be adjusted to several seconds or deleted
// without this, the interactionMode would stay 'undefined' until first mouse or touch event
setTimeout(function() {
  if (!body.classList.contains('mousing') || body.classList.contains('touching')) {
    registerTouch();
  }
}, 1000);
/* fix, so that scrolling is possible */

html,
body {
  height: 110%;
}
Mouse or touch me

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 (tactile) peut créer des problèmes.

A effectué des tests sur divers ordinateurs, tablettes, téléphones sous Linux, iPhone, Android. Bizarre qu'il n'y ait pas de solution facile à toute épreuve. Le problème survient lorsque certaines personnes qui ont Touch et aucune souris présentent toujours des événements Touch and Mouse à l'application. Étant donné que vous souhaitez prendre en charge les instances uniquement de la souris et tactiles, vous souhaitez traiter les deux, mais cela entraîne une double occurrence des interactions utilisateur. Si peut savoir que la souris n'est pas présente sur le périphérique, alors peut savoir ignorer les événements de souris factices/insérés. Indicateur de réglage essayé si MouseMove est rencontré, mais certains navigateurs jettent de faux MouseMove ainsi que MouseUp et MouseDown. J'ai essayé d'examiner les horodatages, mais je me suis dit que c'était trop risqué. Conclusion: les navigateurs qui ont créé les événements de souris factices ont toujours inséré un seul MouseMove juste avant le MouseDown inséré. Dans 99,99% des cas, sur un système équipé d'une vraie souris, il existe plusieurs événements MouseMove consécutifs - au moins deux. Par conséquent, déterminez si le système rencontre deux événements MouseMove consécutifs et déclarez qu’il n’ya pas de souris 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 vais m'en tenir jusqu'à ce que je trouve une meilleure solution. - Jim W

0
jwasch

Comme d'autres l'ont fait remarquer, il n'est pas fiable de détecter définitivement s'ils ont ou non une souris. 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, au moins à l'échelle d'un document.

Les événements tactiles et les événements de souris sont exclusifs. Cela peut donc aider quelque peu à prendre différentes actions. Le problème est que les événements tactiles sont plus proches des événements haut/bas/en mouvement de la souris et déclenchent également un événement clic.

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 concernant votre interface. Je suis en supposant qu'avec le manque de souris, vous voulez un tapot pour avoir un aperçu, alors qu'un clic fait une action différente à cause de l'aperçu en survol.

Si tel est le cas, vous pouvez adopter une approche un peu paresseuse en matière de détection:

Un événement onclick sera toujours précédé d'un événement onmouseover avec une souris. Alors notez que la souris est au-dessus de l'élément sur lequel vous avez cliqué.

Vous pouvez le faire avec un événement onmousemove couvrant l’ensemble du document. Vous pouvez utiliser event.target pour enregistrer l’élément sur lequel réside la souris. Ensuite, dans vos événements onclick, vous pouvez vérifier si la souris survole ou non l'élément sur lequel vous cliquez (ou un enfant de l'élément).

À partir de là, vous pouvez choisir de vous fier à l'événement click pour les deux et d'effectuer une action A ou B en fonction du résultat. L'action B pourrait n'être rien si certains périphériques tactiles n'émettent pas d'événement click (vous devrez plutôt vous fier aux événements ontouch *).

0
Luke

Jetez un coup d’œil à modenizr l’une de ses caractéristiques est le toucher

http://modernizr.com/docs/#features-misc

Bien que je n’ai pas complètement testé cela semble fonctionner très bien 

Ceci est également lié à la page modernizr http://www.html5rocks.com/fr/mobile/touchandmouse/

0
exussum

Je viens de trouver une solution que je trouve assez élégante.

// flag as mouse interaction by default
var isMouse = true;

// detect a touch event start and flag it
$(window).on('touchstart', function () {
  // if triggers touchstart, toggle flag
  // since touch events come before mouse event / click
  // callback of mouse event will get in callback
  // `isMouse === false`
  isMouse = false;
});

// now the code that you want to write
// should also work with `mouse*` events
$('a.someClass').on('click', function () {
  if (isMouse) {
    // interaction with mouse event
    // ...
  } else {
    // reset for the next event detection
    // this is crucial for devices that have both
    // touch screen and mouse
    isMouse = true;

    // interaction with touch event
    // ...
  }
});
0
Koala Yeung