web-dev-qa-db-fra.com

Requête de média pour détecter si le périphérique est un écran tactile

Quel est le moyen le plus sûr, en utilisant des requêtes de médias, de faire quelque chose qui ne se passe pas sur un périphérique tactile? S'il n'y a aucun moyen, suggérez-vous d'utiliser une solution JavaScript telle que !window.Touch ou Modernizr?

105
JJJollyjim

Je suggérerais d’utiliser modernizr et d’utiliser ses fonctions de requête multimédia. 

if (Modernizr.touch){
   // bind to touchstart, touchmove, etc and watch `event.streamId`
} else {
   // bind to normal click, mousemove, etc
}

Cependant, en utilisant CSS, il existe des pseudo-classes comme, par exemple, dans Firefox. Vous pouvez utiliser : -moz-system-metric (tactile) . Mais ces fonctionnalités ne sont pas disponibles pour tous les navigateurs. 

Pour Apple , vous pouvez utiliser simplement:

if(window.TouchEvent) {
   //.....
}

Surtout pour Ipad:

if(window.Touch) {
    //....
}

Mais, ces ne fonctionnent pas sur Android.

Modernizr donne des capacités de détection de fonctionnalité, et la détection de fonctionnalité est un bon moyen de coder, plutôt que de coder sur la base des navigateurs.

Éléments tactiles de style

Modernizer ajoute des classes à la balise HTML dans ce but précis. Dans ce cas, touch et no-touch afin de pouvoir styler vos aspects liés au toucher en préfixant vos sélecteurs avec .touch. par exemple. .touch .your-containerCrédits: Ben Swinburne

37
Starx

Il existe en fait une propriété pour cela dans le brouillon de requête multimédia CSS4 .

La fonctionnalité média ‘pointeur’ est utilisée pour interroger sur la présence et précision d'un périphérique de pointage tel qu'une souris. Si un appareil a plusieurs mécanismes d’entrée, il est recommandé à l’UA de signaler le caractéristiques du périphérique de pointage le moins capable du primaire mécanismes d'entrée. Cette requête multimédia prend les valeurs suivantes:

'aucun'
- Le mécanisme de saisie du périphérique n'inclut pas de périphérique de pointage.

'Grossier'
- Le mécanisme de saisie de l'appareil comprend un dispositif de pointage d'une précision limitée.

'bien'
- Le mécanisme de saisie de l'appareil comprend un dispositif de pointage précis.

Ceci serait utilisé comme tel:

/* Make radio buttons and check boxes larger if we have an inaccurate pointing device */
@media (pointer:coarse) {
    input[type="checkbox"], input[type="radio"] {
        min-width:30px;
        min-height:40px;
        background:transparent;
    }
}

J'ai également trouvé un billet dans le projet Chromium lié à cela.

La compatibilité du navigateur peut être testée à Quirksmode . Voici mes résultats (22 janvier 2013):

  • Chrome/Win: fonctionne
  • Chrome/iOS: ça ne marche pas
  • Safari/iOS6: ça ne marche pas
145
Znarkus

Les solutions CSS ne semblent pas être largement disponibles à la mi-2013. Au lieu...

  1. Nicholas Zakas explique que Modernizr applique une classe CSS no-touch lorsque le navigateur ne prend pas en charge le contact. 

  2. Ou détectez en JavaScript avec un simple morceau de code, ce qui vous permet d'implémenter votre propre solution de style Modernizr:

    <script>
        document.documentElement.className += 
        (("ontouchstart" in document.documentElement) ? ' touch' : ' no-touch');
    </script>
    

    Ensuite, vous pouvez écrire votre CSS comme:

    .no-touch .myClass {
        ...
    }
    .touch .myClass {
        ...
    }
    
49
Simon East

Les types de support ne vous permettent pas de détecter les fonctionnalités tactiles dans le cadre de la norme:

http://www.w3.org/TR/css3-mediaqueries/

Donc, il n'y a aucun moyen de le faire régulièrement via CSS ou des requêtes multimédia, vous devrez recourir à JavaScript.

Pas besoin d'utiliser Modernizr, vous pouvez simplement utiliser JavaScript:

<script type="text/javascript">
    var is_touch_device = 'ontouchstart' in document.documentElement;
    if(is_touch_device) alert("touch is enabled!");
</script>
34
Alex W

En 2017, la requête multimédia CSS de la deuxième réponse ne fonctionne toujours pas sur Firefox. J'ai trouvé une solution pour cela: -moz-touch-enabled


Alors, voici la requête multimédia inter-navigateur:

@media (-moz-touch-enabled: 1), (pointer:coarse) {
    .something {
        its: working;
    }
}
23
Sokołow

Il y a en fait une requête de média pour cela: 

@media (hover: none) { … }

En dehors de Firefox, c'est assez bien supporté . Safari et Chrome étant les navigateurs les plus courants sur les appareils mobiles, cela pourrait suffire jusqu'à une adoption plus poussée.

8
Buzut

Cette solution fonctionnera jusqu'à ce que CSS4 soit globalement pris en charge par tous les navigateurs. Quand ce jour vient, utilisez simplement CSS4. mais jusque-là, cela fonctionne pour les navigateurs actuels. 

browser-util.js

export const isMobile = {
  Android: () => navigator.userAgent.match(/Android/i),
  blackberry: () => navigator.userAgent.match(/BlackBerry/i),
  ios: () => navigator.userAgent.match(/iPhone|iPad|iPod/i),
  opera: () => navigator.userAgent.match(/Opera Mini/i),
  windows: () => navigator.userAgent.match(/IEMobile/i),
  any: () => (isMobile.Android() || isMobile.blackberry() || 
  isMobile.ios() || isMobile.opera() || isMobile.windows())
};

en charge:

ancienne manière:

isMobile.any() ? document.getElementsByTagName("body")[0].className += 'is-touch' : null;

nouvelle façon:

isMobile.any() ? document.body.classList.add('is-touch') : null;

Le code ci-dessus ajoutera la classe "is-touch" à la balise body si le périphérique dispose d'un écran tactile. Désormais, n’importe où dans votre application Web où vous auriez des CSS: survolez vous pouvez appeler body:not(.is-touch) the_rest_of_my_css:hover

par exemple:

button:hover

devient:

body:not(.is-touch) button:hover

Cette solution évite d’utiliser modernizer car la librairie modernizer est une très grande bibliothèque. Si tout ce que vous essayez de faire est de détecter les écrans tactiles, ce sera mieux si la taille de la source compilée finale est requise. 

3
Patrick W. McMahon

ajout d'un écran tactile de classe au corps à l'aide de JS ou de jQuery

  //allowing mobile only css
    var isMobile = ('ontouchstart' in document.documentElement && navigator.userAgent.match(/Mobi/));
    if(isMobile){
        jQuery("body").attr("class",'touchscreen');
    }
0
Matoeil

J'ai pu résoudre ce problème en utilisant cette

@media (hover:none), (hover:on-demand) { 
Your class or ID{
attributes
}    
}
0
Robin Mehdee