Zum ersten Mal wieder zusammen
Einführung
Seit fast dreißig Jahren stehen bei der Nutzung von Computern Tastatur und Maus oder Trackpad als wichtigste Eingabegeräte im Mittelpunkt. In den letzten zehn Jahren haben Smartphones und Tablets jedoch ein neues Interaktionsparadigma eingeführt: Touch. Mit der Einführung von Windows 8-Geräten mit Touch-Funktion und jetzt mit der Veröffentlichung des fantastischen Chromebook Pixel mit Touch-Funktion wird die Touch-Funktion nun zu einem erwarteten Bestandteil der Desktop-Nutzung. Eine der größten Herausforderungen besteht darin, Oberflächen zu entwickeln, die nicht nur auf Touch- und Mausgeräten funktionieren, sondern auch auf Geräten, bei denen der Nutzer beide Eingabemethoden verwendet – manchmal sogar gleichzeitig.
In diesem Artikel erfahren Sie, wie Touch-Funktionen in den Browser integriert sind, wie Sie diesen neuen Schnittstellenmechanismus in Ihre vorhandenen Anwendungen einbinden können und wie Touch- und Mauseingabe gut zusammen funktionieren.
Der Status von Touch-Eingaben auf der Webplattform
Das iPhone war die erste beliebte Plattform, die spezielle Touch-APIs in den Webbrowser integriert hatte. Mehrere andere Browseranbieter haben ähnliche API-Schnittstellen erstellt, die mit der iOS-Implementierung kompatibel sind. Diese wird jetzt in der Spezifikation „Touch-Events Version 1“ beschrieben. Touch-Events werden von Chrome und Firefox auf Computern, von Safari auf iOS-Geräten, von Chrome und dem Android-Browser auf Android-Geräten sowie von anderen mobilen Browsern wie dem Blackberry-Browser unterstützt.
Mein Kollege Boris Smus hat ein hervorragendes HTML5Rocks-Tutorial zu Touch-Events geschrieben, das sich immer noch gut für den Einstieg eignet, wenn Sie sich noch nicht mit Touch-Events befasst haben. Wenn Sie noch nicht mit Touch-Events gearbeitet haben, sollten Sie diesen Artikel lesen, bevor Sie fortfahren. Nur zu, ich warte.
Alles erledigt? Nachdem Sie nun die Grundlagen von Touch-Events kennen, besteht die Herausforderung beim Schreiben von Touch-Interaktionen darin, dass sich diese stark von Maus-Events (und Maus-emulierenden Trackpad- und Trackball-Events) unterscheiden können. Obwohl Touch-Oberflächen in der Regel versuchen, Mäuse zu emulieren, ist diese Emulation nicht perfekt oder vollständig. Sie müssen sich wirklich mit beiden Interaktionsstilen auseinandersetzen und möglicherweise jede Oberfläche unabhängig voneinander unterstützen.
Am wichtigsten: Der Nutzer hat möglicherweise einen Touchscreen und eine Maus.
Viele Entwickler haben Websites erstellt, die statisch erkennen, ob eine Umgebung Touch-Events unterstützt, und dann davon ausgehen, dass sie nur Touch-Events (und keine Maus-Events) unterstützen müssen. Diese Annahme ist nicht mehr richtig. Nur weil Touch-Events vorhanden sind, bedeutet das nicht, dass der Nutzer hauptsächlich dieses Eingabegerät per Berührung verwendet. Geräte wie das Chromebook Pixel und einige Windows 8-Laptops unterstützen jetzt BEIDE Eingabemethoden (Maus und Eingabe per Berührung) und weitere werden in naher Zukunft folgen. Auf diesen Geräten ist es für Nutzer ganz natürlich, sowohl die Maus als auch den Touchscreen für die Interaktion mit Anwendungen zu verwenden. „Unterstützt Touchbedienung“ ist also nicht dasselbe wie „Benötigt keine Mausunterstützung“. Sie dürfen das Problem nicht so sehen: „Ich muss zwei verschiedene Interaktionsstile schreiben und zwischen ihnen wechseln.“ Sie müssen sich überlegen, wie beide Interaktionen sowohl zusammen als auch unabhängig voneinander funktionieren. Auf meinem Chromebook Pixel verwende ich häufig das Trackpad, aber ich tippe auch auf den Bildschirm – in derselben Anwendung oder auf derselben Seite mache ich das, was sich im Moment am natürlichsten anfühlt. Andererseits verwenden einige Nutzer von Laptops mit Touchscreen den Touchscreen selten oder gar nicht. Die Eingabe per Berührung sollte also die Maussteuerung nicht deaktivieren oder behindern.
Leider ist es oft schwierig, festzustellen, ob die Browserumgebung eines Nutzers die Eingabe per Berührung unterstützt. Idealerweise sollte ein Browser auf einem Desktop-Computer immer die Unterstützung für Touch-Events anzeigen, damit jederzeit ein Touchscreen-Display angeschlossen werden kann (z. B. wenn ein über einen KVM angeschlossener Touchscreen verfügbar wird). Aus all diesen Gründen sollten eure Anwendungen nicht versuchen, zwischen Touch- und Mauseingabe zu wechseln, sondern einfach beide unterstützen.
Unterstützung für Maus und Touchbedienung
#1 – Klicken und Tippen – die „natürliche“ Reihenfolge
Das erste Problem ist, dass Touch-Oberflächen in der Regel versuchen, Mausklicks zu emulieren. Das ist natürlich notwendig, da Touch-Oberflächen mit Anwendungen funktionieren müssen, die zuvor nur mit Mausereignissen interagiert haben. Sie können dies als Tastenkombination verwenden, da „click“-Ereignisse weiterhin ausgelöst werden, unabhängig davon, ob der Nutzer mit der Maus geklickt oder mit dem Finger auf den Bildschirm getippt hat. Diese Abkürzung hat jedoch einige Probleme.
Zuerst müssen Sie beim Entwerfen komplexerer Touch-Interaktionen vorsichtig sein: Wenn der Nutzer eine Maus verwendet, wird ein Click-Event ausgelöst. Wenn der Nutzer jedoch den Bildschirm berührt, werden sowohl Touch- als auch Click-Events ausgelöst. Bei einem einzelnen Klick ist die Reihenfolge der Ereignisse:
- touchstart
- touchmove
- touchend
- Mouseover
- mousemove
- mousedown
- mouseup
- Klick
Das bedeutet natürlich, dass Sie bei der Verarbeitung von Touch-Events wie „touchstart“ darauf achten müssen, dass Sie nicht auch das entsprechende „mousedown“- und/oder „click“-Event verarbeiten. Wenn Sie die Touch-Events abbrechen können (preventDefault() im Event-Handler aufrufen), werden für Touch-Events keine Maus-Events generiert. Eine der wichtigsten Regeln für Touch-Handler lautet:
Dadurch wird jedoch auch das Standardverhalten des Standardbrowsers (z. B. Scrollen) verhindert. In der Regel wird das Touch-Event jedoch vollständig im Handler verarbeitet und die Standardaktionen SOLLTEN deaktiviert werden. Im Allgemeinen sollten Sie entweder alle Touch-Events verarbeiten und abbrechen oder keinen Handler für dieses Event verwenden.
Zweitens: Wenn ein Nutzer auf einem Mobilgerät auf ein Element auf einer Webseite tippt, die nicht für die mobile Interaktion konzipiert wurde, kommt es zu einer Verzögerung von mindestens 300 Millisekunden zwischen dem Touchstart-Ereignis und der Verarbeitung von Mausereignissen (Mousedown). In den Chrome-Entwicklertools können Sie die Option Touch-Events emulieren aktivieren, um Touch-Oberflächen auf einem System ohne Touchscreen zu testen.
Diese Verzögerung soll dem Browser Zeit geben, um festzustellen, ob der Nutzer eine andere Geste ausführt, insbesondere das Zoomen durch Doppeltippen. Das kann natürlich problematisch sein, wenn Sie eine sofortige Reaktion auf eine Berührung wünschen. Es wird kontinuierlich daran gearbeitet, die Szenarien, in denen diese Verzögerung auftritt, automatisch zu begrenzen.
Die erste und einfachste Möglichkeit, diese Verzögerung zu vermeiden, besteht darin, dem mobilen Browser mitzuteilen, dass auf Ihrer Seite kein Zoomen erforderlich ist. Dies kann über einen festen Darstellungsbereich erfolgen, z. B. durch Einfügen des folgenden Codes in Ihre Seite:
<meta name="viewport" content="width=device-width,user-scalable=no">
Das ist natürlich nicht immer angebracht, da dadurch das Zoomen per Fingergeste deaktiviert wird, was aus Gründen der Barrierefreiheit im Internet erforderlich sein kann. Verwenden Sie diese Option daher nur sparsam, wenn überhaupt. Wenn Sie die Skalierung durch den Nutzer deaktivieren, sollten Sie eine andere Möglichkeit anbieten, die Lesbarkeit des Textes in Ihrer Anwendung zu verbessern. Außerdem gilt diese Verzögerung nicht für Chrome auf Desktop-Geräten, die Touch unterstützen, und für andere Browser auf mobilen Plattformen, wenn die Seite nicht skalierbare Darstellungsbereiche hat.
#2: Mousemove-Ereignisse werden nicht durch Berührung ausgelöst
An dieser Stelle ist es wichtig zu beachten, dass die Emulation von Mausereignissen in einer Touch-Oberfläche in der Regel nicht auf die Emulation von mousemove-Ereignissen ausgeweitet wird. Wenn Sie also ein schönes mausgesteuertes Steuerelement erstellen, das mousemove-Ereignisse verwendet, funktioniert es wahrscheinlich nicht mit einem Touch-Gerät, es sei denn, Sie fügen auch touchmove-Handler hinzu.
Browser implementieren in der Regel automatisch die entsprechende Interaktion für Berührungsinteraktionen auf den HTML-Steuerelementen. HTML5-Bereichssteuerelemente funktionieren also einfach, wenn Sie Berührungsinteraktionen verwenden. Wenn Sie jedoch eigene Steuerelemente implementiert haben, funktionieren diese wahrscheinlich nicht bei Interaktionen, die auf Klicken und Ziehen basieren. Tatsächlich unterstützen einige häufig verwendete Bibliotheken (wie jQueryUI) Touch-Interaktionen auf diese Weise noch nicht nativ (obwohl es für jQueryUI mehrere Monkey-Patch-Lösungen für dieses Problem gibt). Dies war eines der ersten Probleme, auf die ich bei der Aktualisierung meiner Web Audio Playground-Anwendung für die Touchbedienung gestoßen bin. Die Schieberegler basierten auf jQueryUI und funktionierten daher nicht mit Click-and-Drag-Interaktionen. Ich habe auf HTML5-Bereichssteuerungen umgestellt und sie haben funktioniert. Alternativ hätte ich natürlich auch einfach touchmove-Handler hinzufügen können, um die Schieberegler zu aktualisieren, aber das hat einen Haken…
#3: Touchmove und MouseMove sind nicht dasselbe
Eine Falle, in die ich einige Entwickler tappen gesehen habe, ist, dass touchmove- und mousemove-Handler dieselben Codepfade aufrufen. Das Verhalten dieser Ereignisse ist sehr ähnlich, aber es gibt feine Unterschiede: Touch-Ereignisse beziehen sich immer auf das Element, bei dem die Berührung BEGONNEN hat, während Mausereignisse sich auf das Element beziehen, das sich gerade unter dem Mauszeiger befindet. Deshalb gibt es zwar die Ereignisse „mouseover“ und „mouseout“, aber keine entsprechenden Ereignisse „touchover“ und „touchout“, sondern nur „touchend“.
Das kann vor allem dann passieren, wenn Sie das Element entfernen (oder verschieben), das der Nutzer berührt hat. Stellen Sie sich beispielsweise ein Bildkarussell mit einem Touch-Handler für das gesamte Karussell vor, um ein benutzerdefiniertes Scrollverhalten zu unterstützen. Wenn sich die verfügbaren Bilder ändern, entfernen Sie einige <img>-Elemente und fügen andere hinzu. Wenn der Nutzer eines dieser Bilder berührt und Sie es dann entfernen, empfängt Ihr Handler (der sich auf einem Ancestor des img-Elements befindet) keine Touch-Events mehr, da sie an ein Ziel gesendet werden, das sich nicht mehr im Baum befindet. Es sieht dann so aus, als würde der Nutzer seinen Finger an einer Stelle halten, obwohl er ihn möglicherweise bewegt und schließlich entfernt hat.
Sie können dieses Problem natürlich vermeiden, indem Sie keine Elemente entfernen, die Touch-Handler haben (oder deren übergeordnete Elemente Touch-Handler haben), während eine Berührung aktiv ist. Alternativ können Sie statt der Registrierung statischer touchend-/touchmove-Handler warten, bis Sie ein touchstart-Ereignis erhalten, und dann touchmove-/touchend-/touchcancel-Handler zum Ziel des touchstart-Ereignisses hinzufügen (und sie bei end/cancel entfernen). So erhalten Sie weiterhin Ereignisse für die Berührung, auch wenn das Zielelement verschoben oder entfernt wird. Hier können Sie das ausprobieren: Berühren Sie das rote Feld und drücken Sie die Esc-Taste, während Sie es gedrückt halten, um es aus dem DOM zu entfernen.
#4: Touch und :hover
Die Mauszeiger-Metapher trennte die Cursorposition von der aktiven Auswahl. Dadurch konnten Entwickler Mouseover-Effekte verwenden, um Informationen, die für die Nutzer relevant sein könnten, aus- und einzublenden. Die meisten Touch-Oberflächen erkennen jedoch derzeit nicht, wenn ein Finger über einem Ziel „schwebt“. Daher ist es nicht ratsam, semantisch wichtige Informationen (z. B. ein Pop-up mit der Frage „Was ist dieses Steuerelement?“) basierend auf dem Bewegen des Mauszeigers bereitzustellen, es sei denn, Sie bieten auch eine Touch-freundliche Möglichkeit, auf diese Informationen zuzugreifen. Sie müssen vorsichtig sein, wie Sie Hover-Effekte verwenden, um Informationen an Nutzende weiterzugeben.
Interessanterweise kann die CSS-Pseudoklasse „:hover“ in einigen Fällen durch Touch-Oberflächen ausgelöst werden. Wenn Sie auf ein Element tippen, wird es „:active“, solange der Finger auf dem Bildschirm ist, und es erhält auch den Status „:hover“. (Im Internet Explorer ist „:hover“ nur wirksam, solange der Nutzer den Finger auf dem Bildschirm hat. In anderen Browsern bleibt „:hover“ bis zum nächsten Tippen oder bis zur nächsten Mausbewegung wirksam.) Dies ist ein guter Ansatz, um Pop-out-Menüs auf Touch-Oberflächen zum Laufen zu bringen. Ein Nebeneffekt der Aktivierung eines Elements ist, dass auch der :hover-Status angewendet wird. Beispiel:
<style>
img ~ .content {
display:none;
}
img:hover ~ .content {
display:block;
}
</style>
<img src="/awesome.png">
<div class="content">This is an awesome picture of me</div>
Sobald ein anderes Element angetippt wird, ist das Element nicht mehr aktiv und der Mouseover-Effekt verschwindet, so als ob der Nutzer einen Mauszeiger verwendet und ihn vom Element wegbewegt hätte. Sie können den Inhalt in ein <a>-Element einfügen, um ihn auch zu einem Tabstopp zu machen. So kann der Nutzer die zusätzlichen Informationen per Mausbewegung oder -klick, Berührung oder Tastendruck ein- oder ausblenden, ohne dass JavaScript erforderlich ist. Als ich anfing, meinen Web Audio Playground für Touch-Oberflächen zu optimieren, war ich angenehm überrascht, dass meine Pop-out-Menüs bereits gut funktionierten, weil ich diese Art von Struktur verwendet hatte.
Die oben beschriebene Methode funktioniert sowohl für mauszeigerbasierte Oberflächen als auch für Touch-Oberflächen. Im Gegensatz dazu werden „title“-Attribute beim Bewegen des Mauszeigers NICHT angezeigt, wenn das Element aktiviert ist:
<img src="/awesome.png" title="this doesn't show up in touch">
#5: Touch vs. mouse precision
Mäuse haben zwar eine konzeptionelle Dissoziation von der Realität, sind aber extrem genau, da das zugrunde liegende Betriebssystem im Allgemeinen die genaue Pixelpräzision für den Cursor verfolgt. Mobile Entwickler haben dagegen gelernt, dass Berührungen mit dem Finger auf einem Touchscreen nicht so genau sind, vor allem wegen der Größe der Oberfläche des Fingers, wenn er mit dem Bildschirm in Kontakt kommt (und teilweise, weil die Finger den Bildschirm verdecken).
Viele Einzelpersonen und Unternehmen haben umfangreiche Nutzerstudien dazu durchgeführt, wie Anwendungen und Websites für die Interaktion mit den Fingern gestaltet werden können, und es wurden viele Bücher zu diesem Thema geschrieben. Grundsätzlich wird empfohlen, die Größe der Berührungszielbereiche durch Erhöhen des Innenabstands zu vergrößern und die Wahrscheinlichkeit von fehlerhaften Berührungen durch Erhöhen des Abstands zwischen den Elementen zu verringern. (Außenabstände werden bei der Treffererkennung von Berührungs- und Klickereignissen nicht berücksichtigt, Innenabstände dagegen schon.) Eine der wichtigsten Korrekturen, die ich am Web Audio Playground vornehmen musste, war die Vergrößerung der Verbindungspunkte, damit sie leichter berührt werden können.
Viele Browseranbieter, die Touch-Oberflächen unterstützen, haben auch eine Logik in den Browser integriert, die hilft, das richtige Element anzusteuern, wenn ein Nutzer den Bildschirm berührt, und die Wahrscheinlichkeit von fehlerhaften Klicks zu verringern. Dies korrigiert jedoch in der Regel nur Klick-Ereignisse, nicht Bewegungen (obwohl Internet Explorer anscheinend auch mousedown/mousemove/mouseup-Ereignisse modifiziert).
#6: Touch-Handler eingrenzen, um Ruckeln beim Scrollen zu vermeiden
Außerdem ist es wichtig, Touch-Handler nur auf die Elemente zu beschränken, für die sie benötigt werden. Touch-Elemente können sehr bandbreitenintensiv sein. Daher sollten Touch-Handler auf scrollenden Elementen vermieden werden, da die Verarbeitung die Browseroptimierungen für schnelles, ruckelfreies Touch-Scrollen beeinträchtigen kann. Moderne Browser versuchen, auf einem GPU-Thread zu scrollen. Das ist jedoch nicht möglich, wenn sie zuerst mit JavaScript prüfen müssen, ob jedes Touch-Event von der App verarbeitet wird. Hier finden Sie ein Beispiel für dieses Verhalten.
Um dieses Problem zu vermeiden, sollten Sie darauf achten, dass Sie Touch-Handler nur dort anhängen, wo Sie Touch-Events in einem kleinen Teil Ihrer Benutzeroberfläche verarbeiten (nicht z. B. im <body> der Seite). Kurz gesagt: Schränken Sie den Bereich Ihrer Touch-Handler so weit wie möglich ein.
#7: Multi-Touch
Die letzte interessante Herausforderung besteht darin, dass wir zwar von einer „Touch“-Benutzeroberfläche gesprochen haben, die Unterstützung aber fast überall für Multi-Touch gilt. Das bedeutet, dass die APIs mehr als eine Eingabe per Berührung gleichzeitig bereitstellen. Wenn Sie Touch-Eingaben in Ihren Anwendungen unterstützen, sollten Sie berücksichtigen, wie sich mehrere Berührungen auf Ihre Anwendung auswirken könnten.
Wenn Sie bisher Apps entwickelt haben, die hauptsächlich mit der Maus bedient werden, sind Sie es gewohnt, mit maximal einem Cursorpunkt zu arbeiten. Systeme unterstützen in der Regel nicht mehrere Mauscursor. Bei vielen Anwendungen werden Touch-Events nur einer einzelnen Cursor-Oberfläche zugeordnet. Die meisten Hardwaregeräte, die wir für die Eingabe per Berührung auf dem Desktop gesehen haben, können jedoch mindestens zwei gleichzeitige Eingaben verarbeiten. Die meisten neuen Hardwaregeräte scheinen mindestens fünf gleichzeitige Eingaben zu unterstützen. Für die Entwicklung einer Bildschirmtastatur für ein Klavier müssen natürlich mehrere gleichzeitige Eingaben per Berührung unterstützt werden.
Die derzeit implementierten W3C Touch APIs haben keine API, um zu bestimmen, wie viele Berührungspunkte die Hardware unterstützt. Sie müssen also schätzen, wie viele Berührungspunkte Ihre Nutzer benötigen, oder natürlich darauf achten, wie viele Berührungspunkte Sie in der Praxis sehen, und sich entsprechend anpassen. Wenn Sie beispielsweise in einer Klavier-App nie mehr als zwei Berührungspunkte sehen, können Sie eine Benutzeroberfläche für „Akkorde“ hinzufügen. Die PointerEvents API bietet eine API, mit der die Funktionen des Geräts ermittelt werden können.
Wird ausgebessert
Wir hoffen, dass dieser Artikel Ihnen einige Hinweise zu häufigen Herausforderungen bei der Implementierung von Touch- und Mausinteraktionen gegeben hat. Am wichtigsten ist natürlich, dass Sie Ihre App auf Smartphones, Tablets und Computern mit Maus und Touchscreen testen. Wenn Sie keine Touch- und Maushardware haben, können Sie die verschiedenen Szenarien mit der Chrome-Funktion Touch-Events emulieren testen.
Es ist nicht nur möglich, sondern auch relativ einfach, mit diesen Tipps ansprechende interaktive Erlebnisse zu erstellen, die mit Eingaben per Berührung, Mauseingaben und sogar beiden Interaktionsstilen gleichzeitig gut funktionieren.