Was ist der beste Weg, um ein Touchscreen-Gerät mithilfe von JavaScript zu erkennen?

416

Ich habe ein jQuery-Plug-In geschrieben, das sowohl auf Desktop- als auch auf Mobilgeräten verwendet werden kann. Ich habe mich gefragt, ob es mit JavaScript eine Möglichkeit gibt, festzustellen, ob das Gerät über Touchscreen-Funktionen verfügt. Ich verwende jquery-mobile.js, um die Touchscreen-Ereignisse zu erkennen, und es funktioniert unter iOS, Android usw., aber ich möchte auch bedingte Anweisungen schreiben, die darauf basieren, ob das Gerät des Benutzers über einen Touchscreen verfügt.

Ist das möglich?

screenm0nkey
quelle
Dies ist der bessere Weg var x = 'touchstart' in document.documentElement; console.log (x) // return true wenn unterstützt wird // else return false
Risa__B
Warum ist dieser Thread geschützt, wenn noch neue Techniken auftauchen?
Andy Hoffman

Antworten:

139

Update: Bitte lesen Sie die Antwort von blmstr unten, bevor Sie eine ganze Feature-Erkennungsbibliothek in Ihr Projekt ziehen. Das Erkennen der tatsächlichen Touch-Unterstützung ist komplexer, und Modernizr deckt nur einen grundlegenden Anwendungsfall ab.

Modernizr ist eine großartige und einfache Möglichkeit, alle Arten der Feature-Erkennung an jedem Standort durchzuführen.

Es fügt dem HTML-Element einfach Klassen für jedes Feature hinzu.

Sie können diese Funktionen dann problemlos in CSS und JS ausrichten. Zum Beispiel:

html.touch div {
    width: 480px;
}

html.no-touch div {
    width: auto;
}

Und Javascript (jQuery-Beispiel):

$('html.touch #popup').hide();
Alan Christopher Thomas
quelle
88
Modernizr testet nicht auf Touchscreens. Es prüft, ob Berührungsereignisse im Browser vorhanden sind. Siehe den Abschnitt "Verschiedene Tests" in den Dokumenten: modernizr.com/docs/#features-misc
Harry Love
1
Sie können auch einen JS-Test für das Vorhandensein von Berührungsereignissen durchführen, wenn (Modernizr.touch) {/ * Dinge berühren /} sonst {/ gut, nicht * /}
Anatoly G
7
Nach Ansicht von @ harrylove hat Modernizr seit Erscheinen von Windows 8 fälschlicherweise alle Browser meines PCs als berührungskompatibel zurückgegeben.
Anton
3
Update: Die Antwort von blmstr ist besser und eine reine Javascript-Lösung.
Alan Christopher Thomas
1
Wenn Sie Modernizr.touchunerwartet zurückkehren undefined, verfügen Sie möglicherweise über ein angepasstes Modernizr (das Sie auswählen können), das die Erkennung von Berührungsereignissen nicht unterstützt.
Henrik N
678

Haben Sie versucht, diese Funktion zu verwenden? (Dies ist das gleiche wie bei Modernizr.)

function is_touch_device() {  
  try {  
    document.createEvent("TouchEvent");  
    return true;  
  } catch (e) {  
    return false;  
  }  
}

console.log(is_touch_device());

UPDATE 1

document.createEvent("TouchEvent")haben begonnen, truein der neuesten Chrom (v. 17) zurückzukehren. Modernizr hat dies vor einiger Zeit aktualisiert. Überprüfen Sie den Modernizr-Test hier .

Aktualisieren Sie Ihre Funktion folgendermaßen, damit sie funktioniert:

function is_touch_device1() {
  return 'ontouchstart' in window;
}

console.log(is_touch_device1());

UPDATE 2

Ich habe festgestellt, dass das oben Genannte auf IE10 nicht funktioniert (auf MS Surface wird false zurückgegeben). Hier ist das Update:

function is_touch_device2() {
  return 'ontouchstart' in window        // works on most browsers 
  || 'onmsgesturechange' in window;  // works on IE10 with some false positives
};

console.log(is_touch_device2());

UPDATE 3

'onmsgesturechange' in windowwird in einigen IE-Desktop-Versionen true zurückgeben, sodass dies nicht zuverlässig ist. Dies funktioniert etwas zuverlässiger:

function is_touch_device3() {
  return !!('ontouchstart' in window        // works on most browsers 
  || navigator.maxTouchPoints);       // works on IE10/11 and Surface
};

console.log(is_touch_device3());

UPDATE 2018

Die Zeit vergeht und es gibt neue und bessere Möglichkeiten, dies zu testen. Grundsätzlich habe ich Modernizrs Methode zur Überprüfung extrahiert und vereinfacht:

function is_touch_device4() {
    
    var prefixes = ' -webkit- -moz- -o- -ms- '.split(' ');
    
    var mq = function (query) {
        return window.matchMedia(query).matches;
    }

    if (('ontouchstart' in window) || window.DocumentTouch && document instanceof DocumentTouch) {
        return true;
    }

    // include the 'heartz' as a way to have a non matching MQ to help terminate the join
    // https://git.io/vznFH
    var query = ['(', prefixes.join('touch-enabled),('), 'heartz', ')'].join('');
    return mq(query);
}

console.log(is_touch_device4());

Hier verwenden sie die nicht standardmäßige touch-enabledMedienabfragefunktion, die ich für etwas seltsam und schlecht halte. Aber hey, in der realen Welt funktioniert es wohl. In Zukunft (wenn sie von allen unterstützt werden) könnten diese Medienabfragefunktionen zu denselben Ergebnissen führen: pointerund hover.

Schauen Sie sich die Quelle wie Modernizr es tun .

Einen guten Artikel, in dem die Probleme bei der Berührungserkennung erläutert werden, finden Sie unter: Stu Cox: Sie können einen Touchscreen nicht erkennen .

bolmaster2
quelle
20
Der Doppelknall wandelt einen Wert in einen Booleschen Wert um und zwingt die Funktion, entweder trueoder zurückzugeben false. Sie können mehr darüber hier lesen: stackoverflow.com/questions/4686583/…
Rob Flaherty
2
Dies funktioniert nicht mit Opera Mobile 10 oder Internet Explorer Mobile 6 (Windows Mobile 6.5).
doubleJ
17
Das doppelte NOT (!!) ist überflüssig, da der inOperator bereits einen Booleschen Wert ergibt .
Steve
11
'onmsgesturechange'wird auch bei Nicht-Touch-Geräten (PC) als wahr bewertet. window.navigator.msMaxTouchPointsscheint genauer zu sein. Fand es hier .
Steve
6
Es wird unter IE10 unter Windows 8 als wahr ausgewertet, obwohl mein Bildschirm keine Berührungssensoren hat. Ich habe meinen alten Laptop von Windows 7 auf Windows 8
aktualisiert
120

Da Modernizr IE10 unter Windows Phone 8 / WinRT nicht erkennt, ist eine einfache, browserübergreifende Lösung:

var supportsTouch = 'ontouchstart' in window || navigator.msMaxTouchPoints;

Sie müssen immer nur einmal prüfen, da das Gerät Touch nicht plötzlich unterstützt oder nicht mehr unterstützt. Speichern Sie es einfach in einer Variablen, damit Sie es mehrmals effizienter verwenden können.

Matt Stow
quelle
3
'onmsgesturechange' im Fenster erkennt auch "Desktop" IE10 auf Nicht-Touch-Geräten, sodass dies keine zuverlässige Methode zur Ermittlung von Berührungen ist.
Matt Stow
6
Diese Antwort hätte akzeptiert werden müssen, da sie die beste und einfachste und aktuellste ist. In einer Funktion wäre dies meiner Meinung nach konsistenter: return !!('ontouchstart' in window) || !!('msmaxtouchpoints' in window.navigator);(um beide Antworten zu kombinieren) Funktioniert auch in IE10 einwandfrei!
Yeti
Dies sollte die akzeptierte Antwort sein. 'onmsgesturechange' in windowGibt auf dem IE10-Desktop true zurück, auch wenn eine Berührung möglich ist
Sam Thornton,
6
Alles was Sie brauchen:function isTouchDevice() { return 'ontouchstart' in window || !!(navigator.msMaxTouchPoints);}
GFoley83
1
Sogar GFoleys Vorschlag von 'ontouchstart' in Fenster || !! (navigator.msMaxTouchPoints); kehrt in Chrome 30 dev Feb 2014 positiv zurück.
Tom Andersen
37

Unter Verwendung aller obigen Kommentare habe ich den folgenden Code zusammengestellt, der für meine Anforderungen funktioniert:

var isTouch = (('ontouchstart' in window) || (navigator.msMaxTouchPoints > 0));

Ich habe dies auf iPad, Android (Browser und Chrome), Blackberry Playbook, iPhone 4s, Windows Phone 8, IE 10, IE 8, IE 10 (Windows 8 mit Touchscreen), Opera, Chrome und Firefox getestet.

Es schlägt derzeit unter Windows Phone 7 fehl und ich konnte noch keine Lösung für diesen Browser finden.

Hoffe, jemand findet das nützlich.

David
quelle
Gibt es einen Grund, den Sie nicht verwenden können: function is_touch_device () {return !! ('ontouchstart' im Fenster) || !! ('msmaxtouchpoints' im Navigator); };
Sidonaldson
Die Verwendung der Funktion funktioniert, aber ich verwende im Allgemeinen gerne die oben beschriebene Variablenmethode, sodass sie nur einmal getestet wird und schneller ist, wenn ich sie später in meinem Code überprüfe. Außerdem musste ich testen, ob msMaxTouchPoints mehr als 0 war, da IE 10 unter Windows 8 ohne Touchscreen 0 als msMaxTouchPoints zurückgab.
David
kehrt trueauf meinem Firefox 32 unter Windows 7 zurück :(
vsync
Firefox 33 und 33.1 unter Windows 8 zeigen auf meinem System beide falsch an. Wenn Sie Ihren Firefox auf die neueste Version aktualisieren, gibt er trotzdem true zurück? Haben Sie möglicherweise ein Gerät auf Ihrem Computer installiert, das Firefox fälschlicherweise glauben lässt, dass Ihr Computer Berührungen hat?
David
>>> 'ontouchstart' im Fenster >>> true FF 51.0.1 auf Ubuntu
Ravi Gadhia
24

Seit der Einführung von Interaktionsmedienfunktionen können Sie einfach Folgendes tun:

if(window.matchMedia("(pointer: coarse)").matches) {
    // touchscreen
}

https://www.w3.org/TR/mediaqueries-4/#descdef-media-any-pointer

Update (aufgrund von Kommentaren): Die obige Lösung besteht darin, festzustellen, ob ein "Grobzeiger" - normalerweise ein Touchscreen - das primäre Eingabegerät ist. Wenn Sie feststellen möchten, ob ein Gerät mit z. B. einer Maus auch über einen Touchscreen verfügt, können Sie diesen verwendenany-pointer: coarse stattdessen verwenden.

Weitere Informationen finden Sie hier: Erkennen, dass der Browser keine Maus hat und nur berührungsempfindlich ist

Blackbam
quelle
3
Dies ist bei weitem die beste Lösung, danke! Obwohl ich die Verwendung empfehlen würde, (pointer: coarse)da Sie höchstwahrscheinlich nur auf die primäre Eingabe abzielen. Kann in der Produktion verwendet werden, da die wenigen nicht unterstützten Browser nur Desktop-Browser sind. Es gibt einen großartigen Artikel über CSS-Tricks .
Fabian von Ellerts
2
Dies ist die einzige Lösung, die ich getestet habe und die in jeder Situation funktioniert. Vielen Dank!
kaiserkiwi
20

Ich mag dieses:

function isTouchDevice(){
    return typeof window.ontouchstart !== 'undefined';
}

alert(isTouchDevice());
Benny Neugebauer
quelle
12
Es ist nicht erforderlich, einen ternären Ausdruck zu verwenden, um einen Booleschen Wert zurückzugeben. Verwenden Sie einfach den Ausdruck, um den Booleschen Wert zurückzugeben. function isTouchDevice(){ return (window.ontouchstart !== undefined); }
Tim Vermaelen
1
Sie können auch einfach verwenden: var isTouch = 'ontouchstart' in window;Dies funktioniert jedoch nicht mit dem neuesten Chrome (v31), var isTouch = 'createTouch' in window.document;funktioniert immer noch.
Olivier
2
Wie bereits in den Kommentaren der zuvor akzeptierten Frage erwähnt. "Modernizr testet nicht auf Touchscreens. Es testet das Vorhandensein von Touch-Ereignissen im Browser." Ihre Funktion ist technisch hasTouchEvents () nicht isTouchDevice ()
hexalys
Beachten Sie, dass beim Testen ähnlicher Methoden touchstartSurface nur dann nicht als Touch-Gerät erkannt wird, da der IE pointerstattdessen Ereignisse verwendet.
CookieMonster
1
Vielleicht hatte @Nis recht, aber in Firefox 39 wird korrekt false zurückgegeben.
Dan Dascalescu
17

Wenn Sie Modernizr verwenden , ist es Modernizr.touchwie bereits erwähnt sehr einfach zu verwenden .

Ich bevorzuge jedoch eine Kombination aus Modernizr.touchund Testen von Benutzeragenten, um sicher zu gehen.

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
    }

Wenn Sie Modernizr nicht verwenden, können Sie die Modernizr.touchobige Funktion einfach durch ersetzen('ontouchstart' in document.documentElement)

Beachten Sie außerdem, dass Sie durch das Testen des Benutzeragenten iemobileeine größere Auswahl an erkannten Microsoft-Mobilgeräten erhalten als Windows Phone.

Siehe auch diese SO-Frage

Peter-Pan
quelle
8
Viele Bonuspunkte für "Mach etwas Feines" und "Kann das nicht anfassen"
Lee Saxon
Sie suchen mehrmals nach denselben Geräten und führen mehrere Regexes durch, wenn Sie nur eines verwenden können. Außerdem wird bei Groß- und Kleinschreibung nicht zwischen Groß- und Kleinschreibung unterschieden, aber die Zeichenfolge ist bereits in Kleinbuchstaben geschrieben.
Caesarsol
1
das sollte reichen:/(iphone|ipod|ipad|android|iemobile|blackberry|bada)/.test(window.navigator.userAgent.toLowerCase())
caesarsol
Gibt es einen Grund, Kleinbuchstaben zu verwenden oder die Übereinstimmung zwischen Groß- und Kleinschreibung zu unterscheiden? Wann würden "iOS", "Android" oder "IEMobile" ein anderes Gehäuse verwenden?
Henrik N
14

Wir haben die Modernizr-Implementierung ausprobiert, aber das Erkennen der Berührungsereignisse ist nicht mehr konsistent (IE 10 verfügt über Berührungsereignisse auf dem Windows-Desktop, IE 11 funktioniert, da Berührungsereignisse gelöscht und eine Zeiger-API hinzugefügt wurden).

Deshalb haben wir uns entschlossen, die Website als Touch-Site zu optimieren, solange wir nicht wissen, welchen Eingabetyp der Benutzer hat. Dies ist zuverlässiger als jede andere Lösung.

Unsere Untersuchungen haben ergeben, dass sich die meisten Desktop-Benutzer vor dem Klicken mit der Maus über den Bildschirm bewegen, damit wir sie erkennen und das Verhalten ändern können, bevor sie auf etwas klicken oder den Mauszeiger bewegen können.

Dies ist eine vereinfachte Version unseres Codes:

var isTouch = true;
window.addEventListener('mousemove', function mouseMoveDetector() {
    isTouch = false;
    window.removeEventListener('mousemove', mouseMoveDetector);
});
Martin Lantzsch
quelle
Computer haben heute sowohl Touch als auch Maus ... Sie müssen unterscheiden. Es ist ein absolutes Muss zu wissen, ob es sich nur um Berührung, Maus oder beides handelt. 3 verschiedene Zustände.
vsync
1
Ja, du hast recht, aber das ist sehr schwer. Im besten Fall ist Ihre Anwendung so konzipiert, dass sie von jedem Eingabecontroller verwendet werden kann, und es ist egal, ob der Benutzer über einen Touchscreen, eine Maus, eine Tastatur oder alles zusammen verfügt.
Martin Lantzsch
1
Das Verhalten des Benutzers ist mehr wert als eine echte Information darüber, welche Art von Gerät der Benutzer hat. Wenn Sie wissen, dass der Benutzer eine Maus, einen Touchscreen und eine Tastatur hat - was dann? Behandeln Sie das Verhalten (Mousemove, Touchmove, Keydown usw.). Benutzer können ihren Eingabetyp zur "Laufzeit" ändern. Dies ist ein echtes Problem, wenn Sie eine echte Anwendung entwickeln, die 8 bis 5 ohne erneutes Laden verwendet wird.
Martin Lantzsch
2
+1 Pragmatisch gesehen ist dies die beste Antwort für mich. Zum Beispiel habe ich Datagrids. Diese Datenraster zeigen ein "Bearbeitungssymbol" zum Berühren zum Bearbeiten oder ein Kontextmenü für weitere Optionen. Wenn eine Mausbewegung erkannt wird, entferne ich das Symbol (spart Platz im Raster) und Benutzer können doppelklicken oder mit der rechten Maustaste klicken.
Programmierer
3
Chrom auf Touch-Geräten löst gelegentlich
Mausbewegungen aus
9

Geige arbeiten

Ich habe es so erreicht;

function isTouchDevice(){
    return true == ("ontouchstart" in window || window.DocumentTouch && document instanceof DocumentTouch);
}

if(isTouchDevice()===true) {
    alert('Touch Device'); //your logic for touch device
}
else {
    alert('Not a Touch Device'); //your logic for non touch device
}
Aamir Shahzad
quelle
Windows Surface Tablet wird nicht erkannt
Dan Beaulieu
@DanBeaulieu können Sie bitte gerätespezifisch sein, da ich Windows Phone habe, für das es einwandfrei funktioniert. Außerdem habe ich es in meiner Anwendung QA: ED verwendet. Ich werde es erneut überprüfen und die Antwort aktualisieren. Entschuldigung für die Unannehmlichkeiten
Aamir Shahzad
Ich bin mir nicht sicher, in welchem ​​Jahr, es ist ein Windows Surface Pro, der einem Kollegen gehört. Nach dem Hinzufügen von modernizr haben wir es zum Laufen gebracht.
Dan Beaulieu
Dies hat Non-Touch auf meinem Windows 7-Computer und Touch auf einem Windows 8-Laptop mit Touchscreen und einem Android 4.4 MotoX-Telefon korrekt gemeldet.
Clay Nichols
Gibt ein falsches Positiv in Chrome (46) auf meinem Mac
Patrick Fabrizius
9

Es gibt etwas Besseres als zu überprüfen, ob sie einen Touchscreen haben, zu überprüfen, ob sie ihn verwenden, und das ist einfacher zu überprüfen.

if (window.addEventListener) {
    var once = false;
    window.addEventListener('touchstart', function(){
        if (!once) {
            once = true;
            // Do what you need for touch-screens only
        }
    });
}
Ivan Castellanos
quelle
6

Dieser funktioniert auch in Windows Surface Tablets gut !!!

function detectTouchSupport {
msGesture = window.navigator && window.navigator.msPointerEnabled && window.MSGesture,
touchSupport = (( "ontouchstart" in window ) || msGesture || window.DocumentTouch &&     document instanceof DocumentTouch);
if(touchSupport) {
    $("html").addClass("ci_touch");
}
else {
    $("html").addClass("ci_no_touch");
}
}
Sathiyamoorthy
quelle
4

Ich habe Teile des obigen Codes verwendet, um festzustellen, ob eine Berührung vorliegt, sodass meine Fancybox-Iframes auf Desktop-Computern und nicht bei Berührung angezeigt werden. Ich habe festgestellt, dass Opera Mini für Android 4.0 sich immer noch als Non-Touch-Gerät registriert, wenn nur der Code von blmstr verwendet wird. (Weiß jemand warum?)

Am Ende habe ich verwendet:

<script>
$(document).ready(function() {
    var ua = navigator.userAgent;
    function is_touch_device() { 
        try {  
            document.createEvent("TouchEvent");  
            return true;  
        } catch (e) {  
            return false;  
        }  
    }

    if ((is_touch_device()) || ua.match(/(iPhone|iPod|iPad)/) 
    || ua.match(/BlackBerry/) || ua.match(/Android/)) {
        // Touch browser
    } else {
        // Lightbox code
    }
});
</script>
Geliebt
quelle
Könnten Sie bitte erklären, warum Sie keinen einzelnen Match-Aufruf mit einem einzelnen regulären Ausdruck verwenden /iPhone|iPod|iPad|Android|BlackBerry/?
user907860
Opera Mini führt das Rendern auf den Servern von Opera und nicht auf dem Gerät selbst aus. Auf diese Weise ist es etwas seltsam.
Bluesmoon
4

Das größte Problem beim Versuch, Berührungen zu erkennen, sind Hybridgeräte, die sowohl Berührungen als auch das Trackpad / die Maus unterstützen. Selbst wenn Sie richtig erkennen können, ob das Gerät des Benutzers Touch unterstützt, müssen Sie wirklich erkennen, welches Eingabegerät der Benutzer gerade verwendet. Hier finden Sie eine detaillierte Beschreibung dieser Herausforderung und eine mögliche Lösung .

Grundsätzlich besteht der Ansatz, um herauszufinden, ob ein Benutzer gerade den Bildschirm berührt oder stattdessen eine Maus / ein Trackpad verwendet hat, darin, sowohl ein touchstartals auch ein mouseoverEreignis auf der Seite zu registrieren :

document.addEventListener('touchstart', functionref, false) // on user tap, "touchstart" fires first
document.addEventListener('mouseover', functionref, false) // followed by mouse event, ie: "mouseover"

Eine Berührungsaktion löst beide Ereignisse aus, wobei erstere ( touchstart) auf den meisten Geräten immer an erster Stelle steht. Wenn Sie sich also auf diese vorhersehbare Abfolge von Ereignissen verlassen, können Sie einen Mechanismus erstellen can-touch, der dem Dokumentstamm dynamisch eine Klasse hinzufügt oder daraus entfernt , um den aktuellen Eingabetyp des Benutzers zu diesem Zeitpunkt im Dokument wiederzugeben:

;(function(){
    var isTouch = false //var to indicate current input type (is touch versus no touch) 
    var isTouchTimer 
    var curRootClass = '' //var indicating current document root class ("can-touch" or "")
     
    function addtouchclass(e){
        clearTimeout(isTouchTimer)
        isTouch = true
        if (curRootClass != 'can-touch'){ //add "can-touch' class if it's not already present
            curRootClass = 'can-touch'
            document.documentElement.classList.add(curRootClass)
        }
        isTouchTimer = setTimeout(function(){isTouch = false}, 500) //maintain "istouch" state for 500ms so removetouchclass doesn't get fired immediately following a touch event
    }
     
    function removetouchclass(e){
        if (!isTouch && curRootClass == 'can-touch'){ //remove 'can-touch' class if not triggered by a touch event and class is present
            isTouch = false
            curRootClass = ''
            document.documentElement.classList.remove('can-touch')
        }
    }
     
    document.addEventListener('touchstart', addtouchclass, false) //this event only gets called when input type is touch
    document.addEventListener('mouseover', removetouchclass, false) //this event gets called when input type is everything from touch to mouse/ trackpad
})();

Weitere Details hier .

Coco Puffs
quelle
3

Schauen Sie sich diesen Beitrag an , er enthält einen wirklich schönen Code-Ausschnitt darüber, was zu tun ist, wenn Touch-Geräte erkannt werden, oder was zu tun ist, wenn ein Touchstart-Ereignis aufgerufen wird:

$(function(){
  if(window.Touch) {
    touch_detect.auto_detected();
  } else {
    document.ontouchstart = touch_detect.surface;
  }
}); // End loaded jQuery
var touch_detect = {
  auto_detected: function(event){
    /* add everything you want to do onLoad here (eg. activating hover controls) */
    alert('this was auto detected');
    activateTouchArea();
  },
  surface: function(event){
    /* add everything you want to do ontouchstart here (eg. drag & drop) - you can fire this in both places */
    alert('this was detected by touching');
    activateTouchArea();
  }
}; // touch_detect
function activateTouchArea(){
  /* make sure our screen doesn't scroll when we move the "touchable area" */
  var element = document.getElementById('element_id');
  element.addEventListener("touchstart", touchStart, false);
}
function touchStart(event) {
  /* modularize preventing the default behavior so we can use it again */
  event.preventDefault();
}
Safran Ali
quelle
3

Ich würde es vermeiden, die Bildschirmbreite zu verwenden, um festzustellen, ob ein Gerät ein Touch-Gerät ist. Es gibt Touchscreens, die viel größer als 699px sind, denken Sie an Windows 8. Navigatior.userAgent kann hilfreich sein, um falsche Postives zu überschreiben.

Ich würde empfehlen, dieses Problem auf Modernizr zu überprüfen .

Möchten Sie testen, ob das Gerät Berührungsereignisse unterstützt oder ein Berührungsgerät ist? Leider ist das nicht dasselbe.

Hybrid
quelle
3

Nein, es ist nicht möglich. Die hervorragenden Antworten sind immer nur teilweise, da jede Methode falsch positive und falsch negative Ergebnisse liefert. Selbst der Browser weiß aufgrund von Betriebssystem-APIs nicht immer, ob ein Touchscreen vorhanden ist, und die Tatsache kann sich während einer Browsersitzung ändern, insbesondere bei Vereinbarungen vom Typ KVM.

Weitere Details finden Sie in diesem ausgezeichneten Artikel:

http://www.stucox.com/blog/you-cant-detect-a-touchscreen/

Der Artikel schlägt vor, dass Sie die Annahmen, die Sie dazu veranlassen, Touchscreens zu erkennen, überdenken. Sie sind wahrscheinlich falsch. (Ich habe meine eigene App überprüft und meine Annahmen waren in der Tat falsch!)

Der Artikel schließt:

Nehmen Sie für Layouts an, dass jeder über einen Touchscreen verfügt. Mausbenutzer können große UI-Steuerelemente viel einfacher verwenden als Touch-Benutzer kleine. Gleiches gilt für Schwebezustände.

Nehmen Sie für Ereignisse und Interaktionen an, dass jeder über einen Touchscreen verfügt. Implementieren Sie Tastatur-, Maus- und Touch-Interaktionen nebeneinander und stellen Sie sicher, dass sich keine gegenseitig blockieren.

Dave Burt
quelle
3

Viele dieser Funktionen erfordern jedoch entweder jQuery oder Javascript-Linters beschweren sich über die Syntax. In Anbetracht Ihrer ersten Frage, die nach einer "JavaScript" -Methode (nicht jQuery, nicht Modernizr) zur Lösung dieses Problems fragt, finden Sie hier eine einfache Funktion, die jedes Mal funktioniert. Es ist auch so minimal wie möglich.

function isTouchDevice() {
    return !!window.ontouchstart;
}

console.log(isTouchDevice());

Ein letzter Vorteil, den ich erwähnen möchte, ist, dass dieser Code Framework- und Geräteunabhängig ist. Genießen!

seanforyou23
quelle
function isTouchScreen() { return window.matchMedia('(hover: none)').matches;}Dies hat bei mir funktioniert, daher füge ich hier einen Beitrag zu dieser Antwort hinzu, da ich auch einen Vanille-JS-Thread erwartet hatte, als Google mich hierher brachte.
Daniel Lavedonio de Lima
2

Es sieht so aus, als ob Chrome 24 jetzt Touch-Ereignisse unterstützt, wahrscheinlich für Windows 8. Der hier veröffentlichte Code funktioniert also nicht mehr. Anstatt zu erkennen, ob Touch vom Browser unterstützt wird, binde ich jetzt sowohl Touch- als auch Click-Ereignisse und stelle sicher, dass nur eines aufgerufen wird:

myCustomBind = function(controlName, callback) {

  $(controlName).bind('touchend click', function(e) {
    e.stopPropagation();
    e.preventDefault();

    callback.call();
  });
};

Und dann nenne es:

myCustomBind('#mnuRealtime', function () { ... });

Hoffe das hilft !

Zauberer
quelle
1
Verwandte Themen
Air
2

Alle unterstützten Browser außer Firefox für den Desktop sind immer WAHR, da Firefox für den Desktop reaktionsschnelles Design für Entwickler bietet, selbst wenn Sie auf den Touch-Button klicken oder nicht!

Ich hoffe, Mozilla wird dies in der nächsten Version beheben.

Ich verwende den Firefox 28-Desktop.

function isTouch()
{
    return !!("ontouchstart" in window) || !!(navigator.msMaxTouchPoints);
}
xicooc
quelle
Es ist immer noch Version 32.0 und sie haben es noch nicht behoben! wahnsinnig. warum kann das nicht toggable sein? Dies gibt immer zurück true:(
vsync
2

jQuery v1.11.3

Die Antworten enthalten viele gute Informationen. Aber in letzter Zeit habe ich viel Zeit damit verbracht, alles zu einer funktionierenden Lösung zusammenzufügen, um zwei Dinge zu erreichen:

  1. Stellen Sie fest, dass es sich bei dem verwendeten Gerät um ein Touchscreen-Gerät handelt.
  2. Stellen Sie fest, dass auf das Gerät getippt wurde.

Neben diesem Beitrag und dem Erkennen von Touchscreen-Geräten mit Javascript fand ich diesen Beitrag von Patrick Lauke äußerst hilfreich: https://hacks.mozilla.org/2013/04/detecting-touch-its-the-why-not-the-how /.

Hier ist der Code ...

$(document).ready(function() {
//The page is "ready" and the document can be manipulated.

    if (('ontouchstart' in window) || (navigator.maxTouchPoints > 0) || (navigator.msMaxTouchPoints > 0))
    {
      //If the device is a touch capable device, then...
      $(document).on("touchstart", "a", function() {

        //Do something on tap.

      });
    }
    else
    {
      null;
    }
});

Wichtig! Die *.on( events [, selector ] [, data ], handler )Methode muss über einen Selektor verfügen, normalerweise ein Element, das das "Touchstart" -Ereignis oder ein ähnliches Ereignis, das mit Berührungen verbunden ist, verarbeiten kann. In diesem Fall ist es das Hyperlink-Element "a".

Jetzt müssen Sie nicht mehr mit dem normalen Mausklick in JavaScript umgehen, da Sie CSS verwenden können, um diese Ereignisse mithilfe von Selektoren für das Hyperlink-Element "a" wie folgt zu behandeln:

/* unvisited link */
a:link 
{

}

/* visited link */
a:visited 
{

}

/* mouse over link */
a:hover 
{

}

/* selected link */
a:active 
{

}

Hinweis: Es gibt auch andere Selektoren ...

serge-k
quelle
1
var isTouchScreen = 'createTouch' in document;

oder

var isTouchScreen = 'createTouch' in document || screen.width <= 699 || 
    ua.match(/(iPhone|iPod|iPad)/) || ua.match(/BlackBerry/) || 
    ua.match(/Android/);

wäre wohl eine gründlichere Überprüfung.

samuel segal
quelle
3
Es wäre gut zu bemerken, dass uasich darauf bezieht navigator.userAgent. Auch die Erkennung anhand der Bildschirmbreite kann zu falschen Ergebnissen führen, wenn jemand einen Browser im Nicht-Vollbildmodus öffnet.
HoLyVieR
1

Ich benutze:

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

in jQuery Mobile 1.0.1

Kennzeichen
quelle
1

Ich hatte auch große Probleme mit verschiedenen Optionen, um in Javascript zu erkennen, ob die Seite auf einem Touchscreen-Gerät angezeigt wird oder nicht. IMO gibt es derzeit keine echte Option, um die Option richtig zu erkennen. Browser melden entweder Berührungsereignisse auf Desktop-Computern (da das Betriebssystem möglicherweise berührungsbereit ist), oder einige Lösungen funktionieren nicht auf allen Mobilgeräten.

Am Ende wurde mir klar, dass ich von Anfang an den falschen Ansatz verfolgte: Wenn meine Seite auf Touch- und Non-Touch-Geräten ähnlich aussehen sollte, sollte ich mir möglicherweise überhaupt keine Gedanken über die Erkennung der Eigenschaft machen müssen: Mein Szenario war um Tooltips über Schaltflächen auf Touch-Geräten zu deaktivieren, da diese zu Doppelklicks führen, bei denen ich ein einziges Tippen wollte, um die Schaltfläche zu aktivieren.

Meine Lösung war, Umgestalten der Ansicht , so dass kein Tooltip über eine Schaltfläche benötigt wurde, und am Ende habe ich nicht brauchen , das Touch - Gerät von Javascript mit Methoden zu erkennen , dass alle ihre Nachteile haben .

Michael
quelle
1

Sie können den Modernizer installieren und ein einfaches Touch-Ereignis verwenden. Dies ist sehr effektiv und funktioniert auf jedem Gerät, auf dem ich es getestet habe, einschließlich der Windows-Oberfläche!

Ich habe eine jsFiddle erstellt

function isTouchDevice(){
    if(Modernizr.hasEvent('touchstart') || navigator.userAgent.search(/Touch/i) != -1){
         alert("is touch");
            return true;
         }else{
            alert("is not touch");
            return false;
    }
}
Endjeechner
quelle
3
Willkommen bei SO! Code an sich (wie unkommentierter Code) ist selten eine Antwort. Sie können diese Antwort verbessern, indem Sie eine Erklärung des Snippets hinzufügen.
ebarr
1

Die praktische Antwort scheint eine zu sein, die den Kontext berücksichtigt:

1) Öffentliche Site (kein Login)
Codieren Sie die Benutzeroberfläche, um mit beiden Optionen zusammenzuarbeiten.

2)
Anmeldeseite Erfassen Sie, ob im Anmeldeformular eine Mausbewegung aufgetreten ist, und speichern Sie diese in einer versteckten Eingabe. Der Wert wird mit den Anmeldeinformationen übergeben und der Sitzung des Benutzers hinzugefügt , sodass er für die Dauer der Sitzung verwendet werden kann.

Jquery, die nur zur Anmeldeseite hinzugefügt werden soll:

$('#istouch').val(1); // <-- value will be submitted with login form

if (window.addEventListener) {
    window.addEventListener('mousemove', function mouseMoveListener(){
        // Update hidden input value to false, and stop listening
        $('#istouch').val(0); 
        window.removeEventListener('mousemove', mouseMoveListener);
    });
} 

(+1 an @ Dave Burt und +1 an @ Martin Lantzsch über ihre Antworten)

Programmierer
quelle
1

Das Problem

Aufgrund von Hybridgeräten, die eine Kombination aus Touch- und Mauseingabe verwenden, müssen Sie in der Lage sein , den Status / die Variable dynamisch zu ändern, mit der gesteuert wird, ob ein Code ausgeführt werden soll, wenn der Benutzer ein Touch-Benutzer ist oder nicht.

Touch-Geräte werden auch mousemovebeim Tippen ausgelöst.

Lösung

  1. Angenommen, die Berührung ist beim Laden falsch.
  2. Warten Sie, bis ein touchstartEreignis ausgelöst wird, und setzen Sie es dann auf true.
  3. Wenn Touchstart ausgelöst wurde, fügen Sie einen Mousemove-Handler hinzu.
  4. Wenn die Zeit zwischen zwei Mausbewegungsereignissen weniger als 20 ms betrug, nehmen Sie an, dass sie eine Maus als Eingabe verwenden. Entfernen Sie das Ereignis, da es nicht mehr benötigt wird und Mousemove ein teures Ereignis für Mausgeräte ist.
  5. Sobald der Touchstart erneut ausgelöst wird (der Benutzer hat wieder Touch verwendet), wird die Variable auf true zurückgesetzt. Und wiederholen Sie den Vorgang, damit er dynamisch bestimmt wird. Wenn durch ein Wunder die Mausbewegung bei Berührung absurd schnell zweimal abgefeuert wird (in meinen Tests ist es praktisch unmöglich, dies innerhalb von 20 ms zu tun), setzt der nächste Berührungsstart sie wieder auf wahr.

Getestet auf Safari iOS und Chrome für Android.

Hinweis: Nicht 100% sicher bei den Zeigerereignissen für MS Surface usw.

Codepen-Demo


const supportsTouch = 'ontouchstart' in window;
let isUsingTouch = false;

// `touchstart`, `pointerdown`
const touchHandler = () => {
  isUsingTouch = true;
  document.addEventListener('mousemove', mousemoveHandler);
};

// use a simple closure to store previous time as internal state
const mousemoveHandler = (() => {
  let time;

  return () => {
    const now = performance.now();

    if (now - time < 20) {
      isUsingTouch = false;
      document.removeEventListener('mousemove', mousemoveHandler);
    }

    time = now;
  }
})();

// add listeners
if (supportsTouch) {
  document.addEventListener('touchstart', touchHandler);
} else if (navigator.maxTouchPoints || navigator.msMaxTouchPoints) {
  document.addEventListener('pointerdown', touchHandler);
}
eisig
quelle
1

Eigentlich habe ich diese Frage recherchiert und alle Situationen berücksichtigt. weil es auch bei meinem Projekt ein großes Problem ist. Damit ich die folgende Funktion erreiche, funktioniert sie für alle Versionen aller Browser auf allen Geräten:

const isTouchDevice = () => {
  const prefixes = ['', '-webkit-', '-moz-', '-o-', '-ms-', ''];
  const mq = query => window.matchMedia(query).matches;

  if (
    'ontouchstart' in window ||
    (window.DocumentTouch && document instanceof DocumentTouch)
  ) {
    return true;
  }
  return mq(['(', prefixes.join('touch-enabled),('), 'heartz', ')'].join(''));
};

Hinweis : Auf jeden Fall gibt dasisTouchDevicenurbooleanWerte zurück.

AmerllicA
quelle
0

Umfang jQuery- supportObjekt:

jQuery.support.touch = 'ontouchend' in document;

Und jetzt können Sie es überall überprüfen, wie folgt:

if( jQuery.support.touch )
   // do touch stuff
vsync
quelle
0

Das scheint für mich bisher gut zu funktionieren:

//Checks if a touch screen
is_touch_screen = 'ontouchstart' in document.documentElement;

if (is_touch_screen) {
  // Do something if a touch screen
}
else {
  // Not a touch screen (i.e. desktop)
}
Lewis James-Odwin
quelle
0

Wenn eine Maus angebracht ist, kann mit einer ziemlich hohen Trefferquote (ich würde praktisch 100% sagen) davon ausgegangen werden, dass der Benutzer die Maus mindestens einen winzigen Abstand bewegt, nachdem die Seite fertig ist - ohne zu klicken. Der folgende Mechanismus erkennt dies. Wenn dies erkannt wird, betrachte ich dies als Zeichen für fehlende Touch-Unterstützung oder, falls unterstützt, als von untergeordneter Bedeutung, wenn eine Maus verwendet wird. Touch-Gerät wird angenommen, wenn es nicht erkannt wird.

BEARBEITEN Dieser Ansatz ist möglicherweise nicht für alle Zwecke geeignet. Es kann verwendet werden, um Funktionen zu steuern, die basierend auf der Benutzerinteraktion auf der geladenen Seite aktiviert werden, z. B. ein Bildbetrachter. Der folgende Code lässt das Mausbewegungsereignis auch auf Geräten ohne Maus gebunden, da es jetzt auffällt. Andere Ansätze können besser sein.

In etwa geht es so (Entschuldigung für jQuery, aber ähnlich in reinem Javascript):

var mousedown, first, second = false;
var ticks = 10;
$(document).on('mousemove', (function(e) {
    if(UI.mousechecked) return;
    if(!first) {
        first = e.pageX;
        return;
        }
    if(!second && ticks-- === 0) {
        second = e.pageX;
        $(document).off('mousemove'); // or bind it to somewhat else
        }
    if(first  && second  && first !== second && !mousedown){
        // set whatever flags you want
        UI.hasmouse = true;
        UI.touch = false;
        UI.mousechecked = true;
    }

    return;
}));
$(document).one('mousedown', (function(e) {
    mousedown = true;
    return;
}));
$(document).one('mouseup', (function(e) {
    mousedown = false;
    return;
}));
cglow
quelle