Pointer events
Ein Großteil der heutigen Webinhalte geht davon aus, dass das Zeigegerät des Nutzers eine Maus ist. Da jedoch viele Geräte andere Arten von Zeigegeräten unterstützen, wie z. B. Stifte/Stylus und Touch-Oberflächen, sind Erweiterungen der bestehenden Zeigegerätemodellierung notwendig. Zeigerereignisse adressieren diesen Bedarf.
Zeigerereignisse sind DOM-Ereignisse, die für ein Zeigegerät ausgelöst werden. Sie sind darauf ausgelegt, ein einheitliches DOM-Ereignismodell zu schaffen, um Zeigegeräte wie Maus, Stift/ Stylus oder Touch (z. B. ein oder mehrere Finger) zu handhaben.
Der Zeiger ist ein hardwareunabhängiges Gerät, das auf eine bestimmte Reihe von Bildschirmkoordinaten zielen kann. Ein einheitliches Ereignismodell für Zeiger kann die Erstellung von Websites und Anwendungen vereinfachen und eine gute Benutzererfahrung bieten, unabhängig von der Hardware des Benutzers. Für Szenarien, in denen gerätespezifische Handhabung erwünscht ist, definiert Zeigerereignisse eine pointerType
-Eigenschaft, um den Gerätetyp zu prüfen, der das Ereignis verursacht hat.
Die Ereignisse, die zur Handhabung von generischen Zeigereingaben benötigt werden, sind analog zu Mausereignissen (mousedown
/pointerdown
, mousemove
/pointermove
usw.). Infolgedessen sind die Typen der Zeigerereignisse absichtlich den Typen der Mausereignisse ähnlich.
Zusätzlich enthält ein Zeigerereignis die üblichen Eigenschaften, die in Mausereignissen vorhanden sind (Client-Koordinaten, Zielelement, Schaltzustände usw.), sowie neue Eigenschaften für andere Formen der Eingabe: Druck, Kontaktgeometrie, Neigung usw. Tatsächlich erbt das PointerEvent
-Interface alle Eigenschaften des MouseEvent
und erleichtert so die Migration von Inhalten von Mausereignissen zu Zeigerereignissen.
Terminologie
aktiver Tastenstatus
Der Zustand, wenn ein Zeiger einen ungleich null-Wert für die buttons
-Eigenschaft hat. Zum Beispiel im Fall eines Stifts, wenn der Stift physischen Kontakt mit dem Digitalisierer hat, oder wenn mindestens eine Taste gedrückt ist, während der Stift schwebt.
aktiver Zeiger
Jedes Zeiger Eingabegerät, das Ereignisse erzeugen kann. Ein Zeiger wird als aktiv angesehen, wenn er weiterhin zusätzliche Ereignisse erzeugen kann. Zum Beispiel wird ein Stift, der sich im "down"-Status befindet, als aktiv angesehen, da er zusätzliche Ereignisse erzeugen kann, wenn der Stift angehoben oder bewegt wird.
Digitalisierer
Ein Erfassungsgerät mit einer Oberfläche, das Kontakt erkennen kann. Am häufigsten ist das Erfassungsgerät ein berührungsempfindlicher Bildschirm, der Eingaben von einem Eingabegerät wie einem Stift/Stylus oder Finger erkennen kann. Einige Erfassungsgeräte können die nahe Nähe des Eingabegeräts erkennen, und der Zustand wird als Schweben dem Maus folgen ausgedrückt.
Treffertest
Der Prozess, den der Browser verwendet, um ein Zielelement für ein Zeigerereignis zu bestimmen. Typischerweise wird dies bestimmt, indem die Position des Zeigers und auch das visuelle Layout der Elemente in einem Dokument auf Bildschirmmedien betrachtet werden.
Zeiger
Eine hardwareunabhängige Darstellung von Eingabegeräten, die auf eine bestimmte Koordinate (oder eine Gruppe von Koordinaten) auf einem Bildschirm zielen kann. Beispiele für Zeiger Eingabegeräte sind Maus, Stift/Stylus und Berührungskontakte.
Zeigerfang
Der Zeigerfang ermöglicht es, dass die Ereignisse für einen Zeiger auf ein bestimmtes Element umgeleitet werden, anstatt auf das normale Ergebnis des Treffertests der Position des Zeigers. Siehe Zeiger erfassen für ein Beispiel.
Hinweis: Zeigerfang unterscheidet sich von Pointer Lock, welches physisch verhindert, dass der Zeiger einen Bereich verlässt.
Zeigerereignis
Schnittstellen
Die primäre Schnittstelle ist die PointerEvent
-Schnittstelle, die über einen Konstruktor
sowie mehrere Ereignistypen und zugehörige globale Ereignishandler verfügt.
Der Standard enthält auch einige Erweiterungen der Element
- und Navigator
-Schnittstellen.
Die folgenden Unterabschnitte enthalten kurze Beschreibungen jeder Schnittstelle und Eigenschaft.
PointerEvent-Schnittstelle
Die PointerEvent
-Schnittstelle erweitert die MouseEvent
-Schnittstelle und verfügt über die folgenden Eigenschaften.
altitudeAngle
Nur lesbar-
Stellt den Winkel zwischen einer Transducerachse (einem Zeiger oder Stylus) und der XY-Ebene eines Gerätdisplays dar.
azimuthAngle
Nur lesbar-
Stellt den Winkel zwischen der YZ-Ebene und der Ebene dar, die sowohl die Transducerachse (einem Zeiger oder Stylus) als auch die Y-Achse enthält.
PointerEvent.persistentDeviceId
Nur lesbar Experimentell-
Eine eindeutige Kennung für das Zeigegerät, das das
PointerEvent
generiert. pointerId
Nur lesbar-
Eine eindeutige Kennung für den Zeiger, der das Ereignis verursacht.
width
Nur lesbar-
Die Breite (Größe auf der X-Achse), in CSS-Pixeln, der Kontaktgeometrie des Zeigers.
height
Nur lesbar-
Die Höhe (Größe auf der Y-Achse), in CSS-Pixeln, der Kontaktgeometrie des Zeigers.
pressure
Nur lesbar-
Der normalisierte Druck der Zeigereingabe im Bereich von
0
bis1
, wobei0
und1
den minimalen und maximalen Druck darstellen, den die Hardware erkennen kann. tangentialPressure
Nur lesbar-
Der normalisierte tangentiale Druck der Zeigereingabe (auch bekannt als Zylinderdruck oder Zylinderstress) im Bereich von
-1
bis1
, wobei0
die neutrale Position der Steuerung darstellt. tiltX
Nur lesbar-
Der Plane-Winkel (in Grad, im Bereich von
-90
bis90
) zwischen der YZ-Ebene und der Ebene, die sowohl die Achse des Zeigers (z.B. Stiftstylus) als auch die Y-Achse enthält. tiltY
Nur lesbar-
Der Plane-Winkel (in Grad, im Bereich von
-90
bis90
) zwischen der XZ-Ebene und der Ebene, die sowohl die Achse des Zeigers (z.B. Stiftstylus) als auch die X-Achse enthält. twist
Nur lesbar-
Die Drehung im Uhrzeigersinn des Zeigers (z.B. Stiftstylus) um seine Hauptachse in Grad mit einem Wert im Bereich von
0
bis359
. pointerType
Nur lesbar-
Gibt den Gerätetyp an, der das Ereignis verursacht hat (Maus, Stift, Berührung usw.).
isPrimary
Nur lesbar-
Gibt an, ob der Zeiger den Primärzeiger dieses Zeigertyps darstellt.
Ereignistypen und globale Ereignishandler
Zeigerereignisse haben zehn Ereignistypen, von denen sieben ähnliche Semantik wie ihre Mausereignis-Pendants haben (down
, up
, move
, over
, out
, enter
, und leave
).
Unten ist eine kurze Beschreibung jedes Ereignistyps.
Ereignis | Beschreibung |
---|---|
pointerover |
Wird ausgelöst, wenn ein Zeiger in die Treffertest-Grenzen eines Elements bewegt wird. |
pointerenter |
Wird ausgelöst, wenn ein Zeiger in die Treffertest-Grenzen eines Elements oder eines seiner Nachkommen bewegt wird, auch infolge eines pointerdown -Ereignisses von einem Gerät, das keine Schwebunterstützung bietet (siehe pointerdown ). |
pointerdown |
Wird ausgelöst, wenn ein Zeiger in den aktiven Tastenstatus geht. |
pointermove |
Wird ausgelöst, wenn ein Zeiger die Koordinaten ändert. Dieses Ereignis wird auch verwendet, wenn die Änderung des Zeigerzustands nicht durch andere Ereignisse gemeldet werden kann. |
pointerup |
Wird ausgelöst, wenn ein Zeiger nicht mehr im aktiven Tastenstatus ist. |
pointercancel |
Ein Browser löst dieses Ereignis aus, wenn er feststellt, dass der Zeiger keine Ereignisse mehr erzeugen kann (zum Beispiel wird das zugehörige Gerät deaktiviert). |
pointerout |
Wird aus verschiedenen Gründen ausgelöst, einschließlich: Der Zeiger wird aus den Treffertest-Grenzen eines Elements bewegt; wenn das pointerup -Ereignis für ein Gerät, das keine Schwebunterstützung bietet, ausgelöst wird (siehe pointerup ); nach dem Auslösen des pointercancel -Ereignisses (siehe pointercancel ); wenn ein Stiftstylus den Bereich verlässt, der durch den Digitalisierer im Hover-Modus erfasst werden kann. |
pointerleave |
Wird ausgelöst, wenn ein Zeiger aus den Treffertest-Grenzen eines Elements bewegt wird. Bei Stiftgeräten wird dieses Ereignis ausgelöst, wenn der Stylus den Hover-Detektionsbereich des Digitalisierers verlässt. |
pointerrawupdate
Experimentell
|
Wird ausgelöst, wenn ein Zeiger Eigenschaften ändert, die keine pointerdown - oder pointerup -Ereignisse auslösen. |
gotpointercapture |
Wird ausgelöst, wenn ein Element Zeigerfang erhält. |
lostpointercapture |
Wird ausgelöst, nachdem der Zeigerfang für einen Zeiger freigegeben wurde. |
Elementerweiterungen
Es gibt drei Erweiterungen der Element
-Schnittstelle:
hasPointerCapture()
-
Gibt an, ob das Element, auf dem es aufgerufen wird, Zeigerfang für den durch die angegebene Zeiger-ID identifizierten Zeiger hat.
releasePointerCapture()
-
Gibt den Zeigerfang frei (stoppt ihn), der zuvor für ein bestimmtes Zeigerereignis eingestellt wurde.
setPointerCapture()
-
Weist ein bestimmtes Element als Fangziel zukünftiger Zeigerereignisse zu.
Navigator-Erweiterung
Die Navigator.maxTouchPoints
-Eigenschaft wird verwendet, um die maximale Anzahl gleichzeitiger Berührungspunkte zu bestimmen, die zu einem bestimmten Zeitpunkt unterstützt werden.
Beispiele
Dieser Abschnitt enthält Beispiele zur grundlegenden Verwendung der Zeigerereignisschnittstellen.
Registrieren von Ereignishandlern
Dieses Beispiel registriert einen Handler für jeden Ereignistyp für das angegebene Element.
<div id="target">Touch me…</div>
function over_handler(event) {}
function enter_handler(event) {}
function down_handler(event) {}
function move_handler(event) {}
function up_handler(event) {}
function cancel_handler(event) {}
function out_handler(event) {}
function leave_handler(event) {}
function rawUpdate_handler(event) {}
function gotCapture_handler(event) {}
function lostCapture_handler(event) {}
function init() {
const el = document.getElementById("target");
// Register pointer event handlers
el.onpointerover = over_handler;
el.onpointerenter = enter_handler;
el.onpointerdown = down_handler;
el.onpointermove = move_handler;
el.onpointerup = up_handler;
el.onpointercancel = cancel_handler;
el.onpointerout = out_handler;
el.onpointerleave = leave_handler;
el.onpointerrawupdate = rawUpdate_handler;
el.ongotpointercapture = gotCapture_handler;
el.onlostpointercapture = lostCapture_handler;
}
document.addEventListener("DOMContentLoaded", init);
Ereigniseigenschaften
Das folgende Beispiel zeigt, wie auf alle Eigenschaften eines Zeigerereignisses zugegriffen wird.
<div id="target">Touch me…</div>
const id = -1;
function process_id(event) {
// Process this event based on the event's identifier
}
function process_mouse(event) {
// Process the mouse pointer event
}
function process_pen(event) {
// Process the pen pointer event
}
function process_touch(event) {
// Process the touch pointer event
}
function process_tilt(tiltX, tiltY) {
// Tilt data handler
}
function process_pressure(pressure) {
// Pressure handler
}
function process_non_primary(event) {
// Non primary handler
}
function down_handler(ev) {
// Calculate the touch point's contact area
const area = ev.width * ev.height;
// Compare cached id with this event's id and process accordingly
if (id === ev.identifier) process_id(ev);
// Call the appropriate pointer type handler
switch (ev.pointerType) {
case "mouse":
process_mouse(ev);
break;
case "pen":
process_pen(ev);
break;
case "touch":
process_touch(ev);
break;
default:
console.log(`pointerType ${ev.pointerType} is not supported`);
}
// Call the tilt handler
if (ev.tiltX !== 0 && ev.tiltY !== 0) process_tilt(ev.tiltX, ev.tiltY);
// Call the pressure handler
process_pressure(ev.pressure);
// If this event is not primary, call the non primary handler
if (!ev.isPrimary) process_non_primary(ev);
}
function init() {
const el = document.getElementById("target");
// Register pointerdown handler
el.onpointerdown = down_handler;
}
document.addEventListener("DOMContentLoaded", init);
Bestimmen des primären Zeigers
In einigen Szenarien kann es mehrere Zeiger geben (zum Beispiel ein Gerät mit einem Touchscreen und einer Maus) oder einen Zeiger, der mehrere Kontaktpunkte unterstützt (zum Beispiel ein Touchscreen, der mehrere Fingerberührungen unterstützt). Die Anwendung kann die isPrimary
-Eigenschaft verwenden, um innerhalb der Menge von aktiven Zeigern einen Hauptzeiger für jeden Zeigertyp zu identifizieren. Wenn eine Anwendung nur einen primären Zeiger unterstützen möchte, kann sie alle Zeigerereignisse ignorieren, die nicht primär sind.
Eine Maus hat nur einen Zeiger, daher wird sie immer der primäre Zeiger sein. Für Berührungseingaben ist ein Zeiger dann als primär zu betrachten, wenn der Benutzer den Bildschirm berührt, als keine anderen aktiven Berührungen vorhanden waren. Bei Stift- und Stylus-Eingaben ist ein Zeiger dann als primär zu betrachten, wenn der Benutzer den Stift zuerst den Bildschirm berührt, als keine anderen aktiven Stifte den Bildschirm berührten.
Bestimmen der Tastenstatus
Einige Zeigergeräte (wie Maus und Stift) unterstützen mehrere Tasten, und das Drücken der Tasten kann chordiert sein (d.h. das Drücken einer zusätzlichen Taste, während eine andere Taste auf dem Zeigergerät bereits gedrückt ist).
Um den Zustand der Tasten zu bestimmen, verwendet Zeigerereignisse die button
und buttons
-Eigenschaften der MouseEvent
-Schnittstelle (von der PointerEvent
erbt).
Die folgende Tabelle zeigt die Werte von button
und buttons
für die verschiedenen Gerätezustände.
Zustand der Gerätetaste | button | buttons |
---|---|---|
Weder Tasten noch Berührung/Stiftkontakt haben sich seit dem letzten Ereignis geändert | -1 |
— |
Mausbewegung ohne gedrückte Tasten, Stift bewegt sich während schweben ohne gedrückte Tasten | — | 0 |
Linke Maustaste, Berührungskontakt, Stiftkontakt | 0 |
1 |
Mittlere Maustaste | 1 |
4 |
Rechte Maustaste, Stift-Barreltaste | 2 |
2 |
X1 (zurück) Maus | 3 |
8 |
X2 (vorwärts) Maus | 4 |
16 |
Stift-Radierertaste | 5 |
32 |
Hinweis: Die button
-Eigenschaft zeigt eine Änderung im Zustand der Taste an. Wenn jedoch, wie im Fall von Berührung, mehrere Ereignisse gleichzeitig auftreten, haben alle denselben Wert.
Erfassen des Zeigers
Der Zeigerfang ermöglicht, dass Ereignisse für ein bestimmtes Zeigerereignis auf ein bestimmtes Element anstelle des normalen Treffertests an der Position des Zeigers umgeleitet werden. Dies kann verwendet werden, um sicherzustellen, dass ein Element weiterhin Zeigerereignisse erhält, auch wenn der Kontakt des Zeigegeräts das Element verlässt (zum Beispiel durch Scrollen oder Schwenken).
Der Zeigerfang bewirkt, dass das Ziel alle nachfolgenden Zeigerereignisse wie über das fangende Ziel betrachtet zu empfangen. Folglich werden pointerover
, pointerenter
, pointerleave
und pointerout
nicht ausgelöst, solange dieser Fang aktiviert ist. Für Touchscreen-Browser, die direkte Manipulation erlauben, wird ein impliziter Zeigerfang auf dem Element aufgerufen, wenn ein pointerdown
-Ereignis ausgelöst wird. Der Fang kann manuell durch Aufrufen von element.releasePointerCapture
auf dem Zielelement aufgehoben werden, oder er wird implizit nach einem pointerup
- oder pointercancel
-Ereignis aufgehoben.
Hinweis: Wenn Sie ein Element im DOM verschieben müssen, dann stellen Sie sicher, setPointerCapture()
nach den DOM-Bewegungen zu rufen, damit setPointerCapture()
es nicht aus den Augen verliert. Zum Beispiel, wenn Sie Element.append()
verwenden müssen, um ein Element woanders hin zu verschieben, dann stellen Sie sicher, setPointerCapture()
erst nach dem Aufruf von Element.append()
darauf zu rufen.
Das folgende Beispiel zeigt, wie der Zeigerfang auf einem Element gesetzt wird.
<div id="target">Touch me…</div>
function downHandler(ev) {
const el = document.getElementById("target");
// Element 'target' will receive/capture further events
el.setPointerCapture(ev.pointerId);
}
function init() {
const el = document.getElementById("target");
el.onpointerdown = downHandler;
}
document.addEventListener("DOMContentLoaded", init);
Das folgende Beispiel zeigt, wie ein Zeigerfang freigegeben wird (wenn ein pointercancel
-Ereignis auftritt. Der Browser macht dies automatisch, wenn ein pointerup
- oder pointercancel
-Ereignis auftritt.
<div id="target">Touch me…</div>
function downHandler(ev) {
const el = document.getElementById("target");
// Element "target" will receive/capture further events
el.setPointerCapture(ev.pointerId);
}
function cancelHandler(ev) {
const el = document.getElementById("target");
// Release the pointer capture
el.releasePointerCapture(ev.pointerId);
}
function init() {
const el = document.getElementById("target");
// Register pointerdown and pointercancel handlers
el.onpointerdown = downHandler;
el.onpointercancel = cancelHandler;
}
document.addEventListener("DOMContentLoaded", init);
touch-action CSS-Eigenschaft
Die touch-action
-CSS-Eigenschaft wird verwendet, um zu bestimmen, ob der Browser sein Standard- (native) Touch-Verhalten (wie Zoomen oder Scrollen) auf eine Region anwenden soll oder nicht. Diese Eigenschaft kann auf alle Elemente außer: nicht ersetzten Inline-Elementen, Tabellenzeilen, Zeilengruppen, Tabellenspalten und Spaltengruppen angewendet werden.
Ein Wert von auto
bedeutet, dass der Browser frei ist, sein Standard-Touch-Verhalten (auf die angegebene Region) anzuwenden, und der Wert none
deaktiviert das Standard-Touch-Verhalten des Browsers für die Region. Die Werte pan-x
und pan-y
bedeuten, dass Berührungen, die auf der angegebenen Region beginnen, nur für horizontales und vertikales Scrollen respektive sind. Der Wert manipulation
bedeutet, dass der Browser Berührungen, die auf dem Element beginnen, nur für Scrollen und Zoomen berücksichtigen kann.
Im folgenden Beispiel wird das Standard-Touch-Verhalten des Browsers für das div
-Element deaktiviert.
<html lang="en">
<body>
<div style="touch-action:none;">Can't touch this…</div>
</body>
</html>
Im folgenden Beispiel wird das Standard-Touch-Verhalten für einige button
-Elemente deaktiviert.
button#tiny {
touch-action: none;
}
Im folgenden Beispiel wird, wenn das target
-Element berührt wird, nur in horizontaler Richtung gescrollt.
#target {
touch-action: pan-x;
}
Kompatibilität mit Mausereignissen
Obwohl die Zeigerereignisschnittstellen es Anwendungen ermöglichen, verbesserte Benutzererfahrungen auf zeigerfähigen Geräten zu schaffen, ist die Realität, dass der Großteil der heutigen Webinhalte nur für Maus-Eingaben ausgelegt ist. Folglich muss der Browser, selbst wenn er Zeigerereignisse unterstützt, trotzdem Mausereignisse verarbeiten, damit Inhalte, die nur Maus-Eingaben voraussetzen, wie vorgesehen ohne direkte Modifikationen funktionieren. Idealerweise muss eine zeigerfähige Anwendung die Maus-Eingaben nicht ausdrücklich behandeln. Da der Browser jedoch Mausereignisse verarbeiten muss, können einige Kompatibilitätsprobleme auftreten, die zu handhaben sind. Dieser Abschnitt enthält Informationen über die Interaktion von Zeigerereignissen und Mausereignissen und die Folgen für Anwendungsentwickler.
Der Browser kann generische Zeigereingaben in Mausereignisse für die Kompatibilität mit mausbasierter Nutzung umwandeln. Diese Zuordnung von Ereignissen wird Kompatibilitätsmausereignisse genannt. Autoren können die Produktion bestimmter Kompatibilitätsmausereignisse durch Abbrechen des pointerdown-Ereignisses verhindern, beachten Sie jedoch:
- Mausereignisse können nur verhindert werden, wenn der Zeiger heruntergedrückt ist.
- Schwebende Zeiger (z.B. eine Maus ohne gedrückte Tasten) können ihre Mausereignisse nicht verhindern.
- Die
mouseover
,mouseout
,mouseenter
, undmouseleave
Ereignisse werden niemals verhindert (selbst wenn der Zeiger heruntergedrückt ist).
Beste Praktiken
Hier sind einige beste Praktiken zu beachten, wenn Sie Zeigerereignisse verwenden:
- Minimieren Sie die Menge an Arbeit, die in Ereignishandlern durchgeführt wird.
- Fügen Sie Ereignishandler zu einem bestimmten Zielelement hinzu (anstatt zum gesamten Dokument oder Knoten weiter oben im Dokumentbaum).
- Das Zielelement (Knoten) sollte groß genug sein, um den größten Kontaktflächenbereich (typischerweise einen Finger-Touch) aufzunehmen. Wenn der Zielbereich zu klein ist, könnte das Berühren zu unerwünschten Ereignissen für angrenzende Elemente führen.
Spezifikationen
Specification |
---|
Pointer Events |
Browser-Kompatibilität
BCD tables only load in the browser
Einige zusätzliche Werte wurden für die CSS-touch-action
-Eigenschaft als Teil der Pointer Events-Spezifikation definiert, jedoch haben diese Werte derzeit nur begrenzte Implementierungsunterstützung.