Détecter les appareils à écran tactile avec Javascript

129

Dans Javascript / jQuery, comment puis-je détecter si le périphérique client a une souris?

J'ai un site qui fait glisser un petit panneau d'informations lorsque l'utilisateur passe la souris sur un élément. J'utilise jQuery.hoverIntent pour détecter le survol, mais cela ne fonctionne évidemment pas sur les appareils à écran tactile comme iPhone / iPad / Android. Donc, sur ces appareils, je voudrais revenir au toucher pour afficher le panneau d'informations.

Brad Robinson
la source
6
Pourquoi ne pouvez-vous pas faire les deux? La fonctionnalité Tap est-elle indésirable sur les appareils sans écran tactile?
EMPraptor
1
Étant donné que certains appareils plus récents ne prennent pas en charge :hover, il est probablement préférable (lors du codage d'une feuille de style pour plusieurs appareils) de l'utiliser :hoverà des fins purement esthétiques.
drudge
@empraptor: bon point - oui je pourrais le faire. Cependant ... nous pensions également à toujours afficher le panneau sur les appareils à écran tactile - auquel cas il faudrait que je puisse détecter le support.
Brad Robinson
Si vous pouvez toujours afficher le panneau sur les appareils à écran tactile, ne pourriez-vous pas l'afficher également sur d'autres appareils? Quelle est la taille du panneau et pourquoi est-il souhaitable de l'afficher uniquement en survol / en tapant?
EMPraptor

Réponses:

12

+1 pour faire hoveret les clickdeux. Une autre façon pourrait être d'utiliser des requêtes multimédias CSS et d'utiliser certains styles uniquement pour les petits écrans / appareils mobiles, qui sont les plus susceptibles d'avoir une fonctionnalité tactile / tap. Donc, si vous avez des styles spécifiques via CSS, et à partir de jQuery, vous vérifiez ces éléments pour les propriétés de style d'appareil mobile, vous pouvez les accrocher pour écrire votre code spécifique au mobile.

Voir ici: http://www.forabeautifulweb.com/blog/about/hardboiled_css3_media_queries/

Moin Zaman
la source
1
Bonne solution, vous pourriez probablement faire quelque chose comme une vérification de survol avec une liaison one () afin qu'elle ne se déclenche que la première fois.
Timothy Perez
Le problème est que si vous ciblez par largeur d'écran, lorsque vous faites pivoter votre appareil (prenons l'iphone 6+ 736x414), il n'aura pas le même style. Donc pas la meilleure solution: /
antoni
266
var isTouchDevice = 'ontouchstart' in document.documentElement;

Remarque : ce n'est pas parce qu'un appareil prend en charge les événements tactiles qu'il s'agit exclusivement d'un appareil à écran tactile. De nombreux appareils (tels que mon Asus Zenbook) prennent en charge à la fois les événements de clic et de toucher, même s'ils ne disposent pas de mécanismes de saisie tactile. Lors de la conception de la prise en charge tactile, incluez toujours la prise en charge des événements de clic et ne supposez jamais qu'un périphérique est exclusivement l'un ou l'autre.

KevBurnsJr
la source
33
Comme décrit dans la documentation Modernizr, cela ne détecte que la capacité du navigateur , pas la capacité de l' appareil ... vous obtiendrez un faux résultat positif sur les appareils sans entrée tactile exécutant un navigateur tactile. Je ne connais pas de moyen de détecter nativement la capacité tactile de l' appareil , sans simplement attendre qu'un événement tactile se produise.
Stu Cox
12
Afin de détecter également IE 10 touch, j'utilise: (window.navigator.msMaxTouchPoints || ('ontouchstart' dans document.documentElement));
Alexander Kellett
2
'ontouchstart' in document.documentElement renvoie incorrectement true sur BlackBerry 9300
Simpler
10
@typhon si le logiciel (Win 8, navigateurs modernes) prend en charge le toucher, cela sera toujours vrai - même si vous utilisez du matériel (bureau, moniteur standard, souris et clavier) qui ne prend pas en charge le toucher. Par conséquent, cette solution est obsolète.
Barney
1
funnyItsNotCamelCaseAsJsIsThroughout. Je veux dire que les gens devront maintenant copier, coller ET modifier le code ... :)
Ross
20

Test trouvé pour window.Touch ne fonctionnait pas sur Android, mais cela fonctionne:

function is_touch_device() {
  return !!('ontouchstart' in window);
}

Voir l'article: Quelle est la meilleure façon de détecter un appareil à «écran tactile» à l'aide de JavaScript?

hallodome
la source
Cela détecte les écrans tactiles, mais soyez prudent car il renvoie VRAI pour les ordinateurs portables avec écrans tactiles. Cela peut poser un problème si vous essayez de distinguer si l'utilisateur provient d'un téléphone / tablette OU d'un ordinateur / ordinateur portable, car pour les ordinateurs portables avec écran tactile, il renvoie VRAI.
Combinez
8
return (('ontouchstart' in window)
      || (navigator.maxTouchPoints > 0)
      || (navigator.msMaxTouchPoints > 0));

Raison de l'utilisation de maxTouchPoints avec msMaxTouchPoints:

Microsoft a déclaré qu'à partir d'Internet Explorer 11, la version préfixée par le fournisseur Microsoft de cette propriété (msMaxTouchPoints) peut être supprimée et recommande d'utiliser à la place maxTouchPoints.

Source: http://ctrlq.org/code/19616-detect-touch-screen-javascript

utilisateur
la source
cela a fonctionné et a fonctionné dans les outils de développement de google chrome simuler l'appareil merci
Behnam Mohammadi
7
if ("ontouchstart" in window || navigator.msMaxTouchPoints) {
    isTouch = true;
} else {
    isTouch = false;
}

Fonctionne partout !!

Espion de code
la source
Et qu'est-ce que cela a à voir avec une souris? (la question réelle)
hexalys
Ce serait plus simple à faireisTouch = "ontouchstart" in window || navigator.msMaxTouchPoints;
Andrew
4

J'utilise:

if(jQuery.support.touch){
    alert('Touch enabled');
}

dans jQuery mobile 1.0.1

marque
la source
2
jQuery recommande de ne pas utiliser jQuery.support en faveur de Modernizr ( modernizr.com ): référence - api.jquery.com/jQuery.support -
Jonathan Marzullo
4

Google Chrome semble renvoyer de faux positifs sur celui-ci:

var isTouch = 'ontouchstart' in document.documentElement;

Je suppose que cela a quelque chose à voir avec sa capacité à "émuler les événements tactiles" (F12 -> paramètres dans le coin inférieur droit -> onglet "substitutions" -> dernière case à cocher). Je sais qu'il est désactivé par défaut, mais c'est ce à quoi je connecte la modification des résultats (la méthode «in» utilisée pour fonctionner dans Chrome). Cependant, cela semble fonctionner, d'après ce que j'ai testé:

var isTouch = !!("undefined" != typeof document.documentElement.ontouchstart);

Tous les navigateurs sur lesquels j'ai exécuté ce code indiquent que le type est "objet" mais je suis plus sûr de savoir que c'est quelque chose mais non défini :-)

Testé sur IE7, IE8, IE9, IE10, Chrome 23.0.1271.64, Chrome pour iPad 21.0.1180.80 et iPad Safari. Ce serait cool si quelqu'un faisait d'autres tests et partageait les résultats.

Cendre
la source
Les deux méthodes renvoient des faux positifs sur PC Win 8 avec FF 23 et Chrome 28. Est-ce toujours le cas ou est-ce parce que j'ai déjà eu un écran tactile connecté à cet ordinateur - probablement avant d'installer FF et Chrome - mais plus maintenant? Je n'ai pas défini d'options "émuler les événements tactiles".
typhon
Euh, c'est toujours une lutte avec le nouveau matériel. Les navigateurs doivent travailler avec les couches d'abstraction du système d'exploitation ... qui n'implémentent pas toujours tout ... bref, avec JS, vous devez vous fier au navigateur :) Il n'y a jamais de méthode universelle.
Ash
Les deux reviennent vrais sur Ubuntu Firefox sur un ordinateur portable non tactile.
NoBugs
4

J'ai écrit ceci pour l'un de mes sites et c'est probablement la solution la plus infaillible. D'autant plus que même Modernizr peut obtenir des faux positifs sur la détection tactile.

Si vous utilisez jQuery

$(window).one({
  mouseover : function(){
    Modernizr.touch = false; // Add this line if you have Modernizr
    $('html').removeClass('touch').addClass('mouse');
  } 
});

ou juste du pur JS ...

window.onmouseover = function(){ 
    window.onmouseover = null;
    document.getElementsByTagName("html")[0].className += " mouse";
}
Timothy Perez
la source
4
Attention cependant: au moins les iPads jettent aussi sur les
souris
14
Damn you Apple!
Timothy Perez
Et les personnes utilisant IE sur une tablette Windows peuvent souhaiter utiliser à la fois le toucher et la souris.
Sebazzz
Ce message a été rédigé avant la création de la tablette Windows.
Timothy Perez
@ s427 - Fecking IE ... il suffit de vérifier IE8. Je ne pense pas qu'il existe des appareils mobiles avec <= IE8.
Timothy Perez
4

Pour mon premier post / commentaire: Nous savons tous que le 'touchstart' est déclenché avant le clic. Nous savons également que lorsque l'utilisateur ouvrira votre page, il ou elle: 1) déplacera la souris 2) cliquera 3) touchera l'écran (pour faire défiler, ou ... :))

Essayons quelque chose:

// -> Démarrer: jQuery

var hasTouchCapabilities = 'ontouchstart' in window && (navigator.maxTouchPoints || navigator.msMaxTouchPoints);
var isTouchDevice = hasTouchCapabilities ? 'maybe':'nope';

//attach a once called event handler to window

$(window).one('touchstart mousemove click',function(e){

    if ( isTouchDevice === 'maybe' && e.type === 'touchstart' )
        isTouchDevice = 'yes';
});

// <- Fin: jQuery

Bonne journée!

Silassare
la source
3

J'ai testé le code suivant mentionné ci-dessus dans la discussion

 function is_touch_device() {
    return !!('ontouchstart' in window);
 }

fonctionne sur Android Mozilla, chrome, Opera, navigateur par défaut Android et safari sur iphone ... tous positifs ...

me semble solide :)

Prasad
la source
Super simple et fonctionne bien pour moi. Testé sur Android (ancien Galaxy Note) et avec des émulateurs (Chrome) et sur iPad.
Ralf
Renvoie un faux positif pour moi sur Chrome.
James
2

Cela fonctionne pour moi:

function isTouchDevice(){
    return true == ("ontouchstart" in window || window.DocumentTouch && document instanceof DocumentTouch);
}
Turtletrail
la source
1
sur combien de plates-formes, de navigateurs, de systèmes d'exploitation, d'appareils avez-vous testé?
BerggreenDK
1
FF, Chrome, Safari sur Android et iOS (iPad)
Turtletrail
1
Assez bien. Je viens de tester sur le bureau et j'ai beaucoup de "indéfini" ce qui rend la structure IF un peu piratée. Si vous ajustez un peu votre valeur de retour, comme ceci: return true == ("ontouchstart" dans window || window.DocumentTouch && instance de document de DocumentTouch); Ensuite, vous avez vrai ou faux :-)
BerggreenDK
2
Dans Chrome, "ontouchstart" dans la fenêtre est vrai sur mon PC sans écran tactile, donc cela ne fonctionne pas. Comme indiqué précédemment, cela teste si le navigateur est tactile. De plus, true == ne fait rien et doit être omis.
rakensi
1
Lorsque j'essaye cela dans Chrome avec l'émulateur intégré, il détecte le toucher lorsqu'il est allumé dans l'émulateur et ne détecte pas le toucher lorsqu'il est éteint. Cela fonctionne bien pour moi. Mais: j'utilise la version courte de Prasad (ci-dessous) qui n'utilise pas le || dans le code de Turtletrail. Et: je m'en fiche si cela fonctionne pour 100% des appareils. 99% feront pour moi.
Ralf
1

Si vous utilisez Modernizr , il est très facile à utiliser Modernizr.touchcomme mentionné précédemment.

Cependant, je préfère utiliser une combinaison de Modernizr.touchtests et de tests d'agent utilisateur, juste pour être sûr.

var deviceAgent = navigator.userAgent.toLowerCase();

var isTouchDevice = Modernizr.touch || 
(deviceAgent.match(/(iphone|ipod|ipad)/) ||
deviceAgent.match(/(android)/)  || 
deviceAgent.match(/(iemobile)/) || 
deviceAgent.match(/iphone/i) || 
deviceAgent.match(/ipad/i) || 
deviceAgent.match(/ipod/i) || 
deviceAgent.match(/blackberry/i) || 
deviceAgent.match(/bada/i));

if (isTouchDevice) {
        //Do something touchy
    } else {
        //Can't touch this
    }

Si vous n'utilisez pas Modernizr, vous pouvez simplement remplacer la Modernizr.touchfonction ci-dessus par('ontouchstart' in document.documentElement)

Notez également que le test de l'agent utilisateur iemobilevous donnera une plus large gamme d'appareils mobiles Microsoft détectés que Windows Phone.

Voir aussi cette question SO

Peter-Pan
la source
2
Est la même réponse pour 4 questions maintenant ... et ce n'est pas une solution pour la question qu'il se pose.
jycr753
1
Je crois que cela répond à la question ici
Peter-Pan
ce n'est pas la réponse mais c'est un indice que je pense pour qui veut détecter si l'appareil est touchable avant que l'utilisateur ne le touche
Shahadat Hossain Khan
1

Dans jQuery Mobile, vous pouvez simplement faire:

$.support.touch

Je ne sais pas pourquoi c'est si non documenté ... mais c'est sûr pour crossbrowser (2 dernières versions des navigateurs actuels).

OZZIE
la source
0

Comme déjà mentionné, un appareil peut prendre en charge à la fois la souris et l'entrée tactile. Très souvent, la question n'est pas "ce qui est pris en charge" mais "ce qui est actuellement utilisé".

Dans ce cas, vous pouvez simplement enregistrer les événements de souris (y compris l'écouteur de survol) et les événements tactiles.

element.addEventListener('touchstart',onTouchStartCallback,false);

element.addEventListener('onmousedown',onMouseDownCallback,false);

...

JavaScript doit automatiquement appeler le bon auditeur en fonction de l'entrée de l'utilisateur. Donc, en cas d'événement tactile,onTouchStartCallback sera déclenché, émulant votre code de survol.

Notez qu'un toucher peut déclencher les deux types d'auditeurs, tactile et souris. Cependant, l'écouteur tactile passe en premier et peut empêcher les écouteurs de souris suivants de se déclencher en appelant event.preventDefault().

function onTouchStartCallback(ev) {
    // Call preventDefault() to prevent any further handling
    ev.preventDefault();
    your code...
}

Lectures complémentaires ici .

user3792852
la source
-3

Pour le développement iPad, j'utilise:

  if (window.Touch)
  {
    alert("touchy touchy");
  }
  else
  {
    alert("no touchy touchy");
  }

Je peux ensuite me lier sélectivement aux événements tactiles (par exemple ontouchstart) ou aux événements basés sur la souris (par exemple onmousedown). Je n'ai pas encore testé sur Android.

Halton
la source
1
Cela ne fonctionne pas avec Opera Mobile 10 ou Internet Explorer Mobile 6 (Windows Mobile 6.5).
doubleJ
4
mauvais conseil crossbrowser / cross OS / multiplateforme.
BerggreenDK