Schnellstart: DOM-Gesten und -Manipulationen (HTML)

[ Dieser Artikel richtet sich an Windows 8.x- und Windows Phone 8.x-Entwickler, die Windows-Runtime-Apps schreiben. Wenn Sie für Windows 10 entwickeln, finden Sie weitere Informationen unter neueste Dokumentation]

Sie können die Benutzerführung für einen Teil der in der Windows-Sprache für die Fingereingabe beschriebenen Basisgesten (z. B. Ziehen, Drehen und Größenänderung) durch einfache Behandlung von Dokumentobjektmodell-Gestenereignissen (DOM) anpassen.

Updates für Windows 8.1: In Windows 8.1 werden eine Reihe von Updates und Verbesserungen für die Zeigereingabe-APIs eingeführt. Weitere Informationen dazu finden Sie unter API-Änderungen für Windows 8.1.

Wenn Sie noch keine Erfahrungen mit der Entwicklung von Apps mit JavaScript haben,: lesen Sie die Informationen in diesen Themen, um sich mit den hier erläuterten Technologien vertraut zu machen.

Erstellen Ihrer ersten App mit JavaScript

Roadmap für Apps mit JavaScript

Informieren Sie sich über Ereignisse unter Schnellstart: Hinzufügen von HTML-Steuerelementen und Behandeln von Ereignissen

App-Features von A bis Z:

In unserer Reihe App-Features von A bis Z können Sie sich genauer über diese Funktion informieren.

Benutzerinteraktion von A bis Z (HTML)

Anpassung der Benutzerinteraktion von A bis Z (HTML)

Richtlinien für die Benutzeroberfläche:

Die Plattform-Steuerelementbibliotheken (HTML und XAML) bieten umfassende Funktionalität für Benutzerinteraktionen, u. a. für Standardinteraktionen, animierte Bewegungseffekte und visuelles Feedback. Wenn Sie keine Unterstützung für angepasste Interaktionen benötigen, sollten Sie diese integrierten Steuerelemente verwenden.

Falls die Funktionalität der Plattformsteuerelemente nicht ausreicht, können Ihnen die folgenden Richtlinien für Benutzerinteraktionen dabei helfen, eine ansprechende, immersive und für alle Eingabemodi einheitliche Interaktionsumgebung bereitzustellen. Diese Richtlinien betreffen in erster Linie Fingereingaben, sie sind jedoch auch für Touchpad-, Maus-, Tastatur- und Stifteingaben relevant.

Beispiele: Sehen Sie sich unter Beispiele für Apps diese Funktionalität in Aktion an.

Anpassung der Benutzerinteraktion von A bis Z

Beispiel für HTML-Bildlauf, -Verschiebung und -Zoomen

Eingabe: Beispiel für die Behandlung von DOM-Zeigerereignissen

Eingabe: Beispiel für instanziierbare Gesten

Ziel: Um mehr über das Lauschen auf sowie Behandeln und Verarbeiten von Basisgesten für Translation, Drehung und Skalierung über Eingaben durch Berührung, Maus, Zeichen-/Eingabestift und DOM-Gestenereignisse zu erfahren,

Voraussetzungen

schlagen Sie unter Schnellstart: Zeiger nach.

In diesem Thema wird vorausgesetzt, dass Sie eine einfache App mit JavaScript erstellen können, die auf der Vorlage „Windows-Bibliothek für JavaScript“ basiert.

Für dieses Lernprogramm ist Folgendes erforderlich:

Zeitaufwand: 30 Minuten.

Was sind Gestikereignisse?

Eine Geste ist eine physische Bewegung, die mit dem Eingabegerät (ein oder mehrere Finger auf einem Touchscreen, Zeichen-/Eingabestiftdigitalisierer, Maus usw.) ausgeführt wird. Diese natürlichen Interaktionen werden Vorgängen in Elementen sowohl im System als auch in Ihrer App zugewiesen. Weitere Informationen finden Sie unter Gesten, Manipulationen und Interaktionen.

Windows stützt sich auf einen grundlegenden Satz von Gesten zur Interaktion mit der Benutzeroberfläche und deren Manipulation.

GesteBeschreibung
TippenTippbewegung

Ein einzelner Kontakt wird festgestellt und sofort wieder gelöst.

Durch das Tippen auf ein Element wird dessen primäre Aktion aufgerufen.

GedrückthaltenGedrückthaltebewegung

Ein einzelner Kontakt wird festgestellt, und der Kontaktpunkt bewegt sich nicht.

Das Gedrückthalten bewirkt, dass ausführliche Informationen oder visuelle Lernelemente (beispielsweise eine QuickInfo oder ein Kontextmenü) angezeigt werden, ohne dass eine Aktion ausgeführt werden muss.

ZiehenZiehbewegung

Mindestens ein Kontakt wird festgestellt, und die Kontaktpunkte bewegen sich in die gleiche Richtung.

Das Ziehen wird in erster Linie für Verschiebungen verwendet, kann jedoch auch zum Schieben, Zeichnen oder Schreiben genutzt werden.

StreifenStreifbewegung

Mindestens ein Kontakt wird festgestellt, und die Kontaktpunkte bewegen sich über eine kurze Strecke in die gleiche Richtung.

Das Streifen wird zum Auswählen, Anzeigen von Befehlen und Schieben verwendet.

DrehenDrehbewegung

Mindestens zwei Kontakte werden festgestellt, und die Kontaktpunkte führen eine Kreisbewegung im oder gegen den Uhrzeigersinn aus.

Das Drehen wird für Rotationen verwendet.

ZusammendrückenZusammendrückbewegung

Mindestens zwei Kontakte werden festgestellt, und die Kontaktpunkte bewegen sich aufeinander zu.

Durch Zusammendrücken können Sie ein Element verkleinern.

AufziehenAufziehbewegung

Mindestens zwei Kontakte werden festgestellt, und die Kontaktpunkte bewegen sich voneinander weg.

Durch Aufziehen können Sie ein Element vergrößern.

Weitere Informationen zu diesen Gesten und ihrer Beziehung zur Windows-Sprache für die Fingereingabe finden Sie unter Design für Interaktion per Fingereingabe.

 

Sie können die Gestenerkennung verwenden, um das Interaktionsmodell Ihrer App zu erweitern, indem Sie auf den einfachen Zeigerereignissen, die unter Schnellstart: Behandeln von Zeigereingaben beschrieben werden, aufbauen. Tatsächlich ist es sehr wahrscheinlich, dass Ihre App Gestikereignisse einbindet (z. B. das Behandeln von Tippbewegungen, Verschiebungen oder Bewegungen durch Ziehbewegungen oder Zoomaktionen durch Zusammendrücken oder Aufziehen) und gleichzeitig Rohzeigerdaten verwendet, um die Erkennung und Verarbeitung von Gesten zu unterstützen.

Ihre App kann mehrere Gesten gleichzeitig verarbeiten (z. B. Vergrößern und Drehen), Zeigerkontakte gruppieren, um ein bestimmtes Element anzusprechen (beispielsweise Zuordnen aller Kontakte zum Ziel des ersten oder primären Kontakts) und die einzelnen Elemente identifizieren, auf die sich bestimmte Gesten oder Zeigerkontakte richten.

Wichtig  Wenn Sie eine eigene Interaktionsunterstützung implementieren, sollten Sie daran denken, dass die Benutzer eine intuitive Umgebung erwarten, die die direkte Interaktion mit den UI-Elementen der App beinhaltet. Es empfiehlt sich, die benutzerdefinierten Interaktionen basierend auf den Plattform-Steuerelementbibliotheken (HTML und XAML) zu modellieren, um auf diese Weise für eine konsistente und intuitive Benutzerumgebung zu sorgen. Die Steuerelemente in diesen Bibliotheken bieten umfassende Funktionen für Benutzerinteraktionen wie Standardinteraktionen, animierte Bewegungseffekte, visuelles Feedback und Barrierefreiheit. Erstellen Sie benutzerdefinierte Interaktionen nur dann, wenn ein eindeutiger, klar umrissener Bedarf besteht und es keine Basisinteraktion gibt, die das gewünschte Szenario unterstützt.

 

Erstellen der Benutzeroberfläche

In diesem Beispiel wird ein Rechteck (target) als Zielobjekt für die Erkennung und Verarbeitung von Zeigereingaben und Gesten verwendet.

Das Rechteck dient als einfacher Farbmischer. Die Farbe des Ziels ändert sich auf der Basis einer RGB-Farbauswahl (Rot, Grün oder Blau) und des Zieldrehwinkels, wie er über die Drehbewegung erfasst wird. (Der Rot-, Grün- oder Blauwert wird anhand des Drehwinkels berechnet.)

Für jedes Zeiger- und Gestenereignis werden Details und die aktuelle Transformationsmatrix, die auf das Ziel angewendet wird, innerhalb des Zielobjekts angezeigt.

Im Folgenden ist der HTML-Code für dieses Beispiel aufgeführt.

<html>
<head>
    <meta charset="utf-8" />
    <title>PointerInput</title>

    <!-- WinJS references -->
    <link href="//Microsoft.WinJS.2.0/css/ui-dark.css" rel="stylesheet" />
    <script src="//Microsoft.WinJS.2.0/js/base.js"></script>
    <script src="//Microsoft.WinJS.2.0/js/ui.js"></script>

    <!-- BasicGesture references -->
    <link href="/css/default.css" rel="stylesheet" />
    <script src="/js/default.js"></script>
</head>
<body>
    <div class="TargetContainer" id="targetContainer">
        <div id="colorMixer">
            <input type="radio" name="color" value="R" title="Red" id="red" class="Red" /><label for="red" id="labelRed">Red</label>
            <input type="radio" name="color" value="G" title="Green" id="green" class="Green" /><label for="green" id="labelGreen">Green</label>
            <input type="radio" name="color" value="B" title="Blue" id="blue" class="Blue" /><label for="blue" id="labelBlue">Blue</label>
            <div id="targetLog"></div>
            <div id="eventLog"></div>
        </div>
    </div>
</body>
</html>

Im Folgenden ist das Cascading Stylesheet (CSS) für dieses Beispiel aufgeführt.

Hinweis  Zeigerereignisse werden bei Verschiebungs- oder Zoominteraktionen nicht ausgelöst. Sie können Verschiebungen und Zoomaktionen für einen Bereich über die CSS-Eigenschaften msTouchAction, overflow und -ms-content-zooming deaktivieren.

 

body {
    overflow: hidden;
    position: relative;
}

div #targetContainer {
/*
Set the width and height properties of the target container to fill the viewport. 
You can set these properties to 100%, but we use 100vw (viewport width) and 100vh (viewport height).
See https://go.microsoft.com/fwlink/?LinkID=301480 for more detail on CSS units supported by Internet Explorer.
*/
    height: 100vw;
    width: 100vh;
    overflow: hidden;
    position: absolute;
}

div #colorMixer {
/*
A manipulation-blocking element is defined as an element that explicitly 
blocks direct manipulation via declarative markup, and instead fires gesture 
events such as MSGestureStart, MSGestureChange, and MSGestureEnd.
*/
    touch-action: none;
    -ms-transform-origin: 0px 0px;
    position: absolute;
    background-color: black;
    border-color: white;
    border-width: thick;
    border-style: solid;
}

div #colorSelector {
    position: relative;
}

div #eventLog {
    -ms-overflow-style:scrollbar;
}

input.Red {
    background-color: rgb(255,0,0);
}

input.Green {
    background-color: rgb(0,255,0);
}

input.Blue {
    background-color: rgb(0,0,255);
}

Lauschen auf Zeiger- und Gestikereignisse

Durch diesen Code werden der Farbmischer und die Farbwähler eingerichtet und die verschiedenen Ereignislistener deklariert.

Für die meisten Fälle wird empfohlen, Zeigerinformationen über das Ereignisargument der Zeigerereignishandler im ausgewählten Programmiersprachenframework abzurufen.

Sollte das Ereignisargument die für die App erforderlichen Zeigerdetails nicht liefern, können Sie über die Methoden getCurrentPoint und getIntermediatePoints oder die Eigenschaften currentPoint und intermediatePoints auf erweiterte Zeigerdaten des Ereignisarguments zugreifen. Wir empfehlen die Verwendung der Methoden getCurrentPoint und getIntermediatePoints, weil sie die Möglichkeit bieten, den Kontext der Zeigerdaten anzugeben.

Zuerst werden die globalen Variablen deklariert, ein Datenobjekt (colorInfo) definiert, um den Zielstatus zu verfolgen, und sowohl der Farbmischer (target) als auch die RGB-Farbwähler initialisiert.

var _width = 640;
var _height = 640;

var _pointerInfo;
var _targetLog;

var _selectedColor;
var _colorRed, _colorGreen, _colorBlue;

// Color-specific data object.
//   value: The color value (r, g, or b)
//   rotation: The rotation value used to calculate color value.
//   matrix: The transform matrix of the target.
function colorInfo(value, rotation, matrix) {
    this.value = value;
    this.rotation = rotation;
    this.matrix = matrix;
}

function initialize() {
    // Configure the target.
    setTarget();

    // Initialize color tracking.
    setColors();
}

Anschließend wird der Farbmischer eingerichtet, dem Objekt wird eine Gestikerkennung (msGesture) zugeordnet, und die verschiedenen Ereignislistener werden deklariert.

Tipp  In diesem Beispiel ist einer Gestikerkennung nur ein Objekt zugeordnet. Falls Ihre App viele Objekte enthält, die manipuliert werden können (z. B. ein Puzzle), erwägen Sie die dynamische Erstellung einer Gestikerkennung nur, wenn die Zeigereingabe für ein Zielobjekt ermittelt wird. Die Gestikerkennung kann zerstört werden, wenn die Manipulation abgeschlossen ist. (Ein Beispiel hierfür finden Sie unter Eingabe: Beispiel für instanziierbare Gesten.) Um den Aufwand für das Erstellen und Zerstören von Gestikerkennungen zu vermeiden, erstellen Sie bei der Initialisierung einen kleinen Pool mit Gestikerkennungen, und weisen Sie sie nach Bedarf dynamisch zu.

 

// Configure the interaction target.
function setTarget() {
    //  Set up the target position, size, and transform.
    colorMixer.style.width = _width + "px";
    colorMixer.style.height = _height + "px";
    colorMixer.style.msTransform = (new MSCSSMatrix()).
        translate((window.innerWidth - parseInt(colorMixer.style.width)) / 2.0,
        (window.innerHeight - parseInt(colorMixer.style.height)) / 2.0);

    // Create gesture recognizer.
    var msGesture = new MSGesture();
    msGesture.target = colorMixer;
    colorMixer.gesture = msGesture;
    // Expando property for handling multiple pointer devices.
    colorMixer.gesture.pointerType = null;

    // Expando property to track pointers.
    colorMixer.pointers = [];

    // Declare event handlers.
    colorMixer.addEventListener("pointerdown", onPointerDown, false);
    colorMixer.addEventListener("pointerup", onPointerUp, false);
    colorMixer.addEventListener("pointercancel", onPointerCancel, false);
    colorMixer.addEventListener("lostpointercapture", onLostPointerCapture, false);
    colorMixer.addEventListener("MSGestureChange", onMSGestureChange, false);
    colorMixer.addEventListener("MSGestureTap", onMSGestureTap, false);
    colorMixer.addEventListener("MSGestureEnd", onMSGestureEnd, false);
    colorMixer.addEventListener("MSGestureHold", onMSGestureHold, false);
}

Zum Schluss werden die RGB-Farbwähler (mit Ereignislistenern) und das colorInfo-Objekt initialisiert.

// Initialize values and event listeners for color tracking.
function setColors() {
    var m = new MSCSSMatrix(colorMixer.style.msTransform);
    _colorRed = new colorInfo(0, 0, m);
    _colorGreen = new colorInfo(0, 0, m);
    _colorBlue = new colorInfo(0, 0, m);

    document.getElementById("red").addEventListener("click", onColorChange, false);
    document.getElementById("green").addEventListener("click", onColorChange, false);
    document.getElementById("blue").addEventListener("click", onColorChange, false);
}

// Re-draw target based on transform matrix associated with color selection.
function onColorChange(e) {
    switch (e.target.id) {
        case "red":
            colorMixer.style.msTransform = _colorRed.matrix;
            break;
        case "green":
            colorMixer.style.msTransform = _colorGreen.matrix;
            break;
        case "blue":
            colorMixer.style.msTransform = _colorBlue.matrix;
            break;
    }
    _selectedColor = e.target.id;

    eventLog.innerText = "Color change";
    targetLog.innerText = colorMixer.style.msTransform;
}

Behandeln des Zeiger-nach-unten-Ereignisses

Bei einem Zeiger-nach-unten-Ereignis wird die ausgewählte RGB-Farbe ermittelt und der Zeiger mit der Gestikerkennung durch Aufrufen der addPointer-Methode verknüpft. Die Abfolge und die pointerType-Eigenschaft werden verfolgt, um den Zeiger und die Gestikerkennung bei Bedarf neu zu verknüpfen.

Wird keine Farbe ausgewählt, wird das Zeigerereignis ignoriert.

// Pointer down handler: Attach the pointer to a gesture object.
function onPointerDown(e) {
    // Do not attach pointer if no color selected.
    if (_selectedColor === undefined)
        return;
    _selectedColor = getSelectedColor();

    // Process pointer.
    if (e.target === this) {
        this.style.borderStyle = "double";
        //  Attach first contact and track device.
        if (this.gesture.pointerType === null) {
            this.gesture.addPointer(e.pointerId);
            this.gesture.pointerType = e.pointerType;
        }
            // Attach subsequent contacts from same device.
        else if (e.pointerType === this.gesture.pointerType) {
            this.gesture.addPointer(e.pointerId);
        }
            // New gesture recognizer for new pointer type.
        else {
            var msGesture = new MSGesture();
            msGesture.target = e.target;
            e.target.gesture = msGesture;
            e.target.gesture.pointerType = e.pointerType;
            e.target.gesture.addPointer(e.pointerId);
        }
    }
    eventLog.innerText = "Pointer down";
}

// Get the current color.
function getSelectedColor() {
    var colorSelection = document.getElementsByName("color");
    for (var i = 0; i < colorSelection.length; i++) {
        if (colorSelection[i].checked)
            return colorSelection[i].id;
    }
}

Behandeln des Gestikereignisses

Im folgenden Code werden die Translations- (Ziehen oder Streifen), Rotations- und Skalierungsgesten (Zusammendrücken oder Aufziehen) verarbeitet.

// Gesture change handler: Process gestures for translation, rotation, and scaling.
// For this example, we don't track pointer movements.
function onMSGestureChange(e) {
    // Get the target associated with the gesture event.
    var elt = e.gestureObject.target;
    // Get the matrix transform for the target.
    var matrix = new MSCSSMatrix(elt.style.msTransform);

    // Process gestures for translation, rotation, and scaling.
    e.target.style.msTransform = matrix.
        translate(e.offsetX, e.offsetY).
        translate(e.translationX, e.translationY).
        rotate(e.rotation * 180 / Math.PI).
        scale(e.scale).
        translate(-e.offsetX, -e.offsetY);

    // Mix the colors based on rotation value.
    switch (_selectedColor) {
        case "red":
            _colorRed.rotation += ((e.rotation * 180 / Math.PI));
            _colorRed.rotation = _colorRed.rotation % 360;
            targetLog.innerText = _colorRed.rotation.toString();
            if (_colorRed.rotation >= 0)
                _colorRed.value = parseInt(Math.abs(_colorRed.rotation) * (256 / 360));
            else
                _colorRed.value = parseInt((360 - Math.abs(_colorRed.rotation)) * (256 / 360));
            document.getElementById("labelRed").innerText = _colorRed.value.toString();
            _colorRed.matrix = matrix;
            break;
        case "green":
            _colorGreen.rotation += ((e.rotation * 180 / Math.PI));
            _colorGreen.rotation = _colorGreen.rotation % 360;
            targetLog.innerText = _colorGreen.rotation.toString();
            if (_colorGreen.rotation >= 0)
                _colorGreen.value = parseInt(Math.abs(_colorGreen.rotation) * (256 / 360));
            else
                _colorGreen.value = parseInt((360 - Math.abs(_colorGreen.rotation)) * (256 / 360));
            document.getElementById("labelGreen").innerText = _colorGreen.value.toString();
            _colorGreen.matrix = matrix;
            break;
        case "blue":
            _colorBlue.rotation += ((e.rotation * 180 / Math.PI));
            _colorBlue.rotation = _colorBlue.rotation % 360;
            if (_colorBlue.rotation >= 0)
                _colorBlue.value = parseInt(Math.abs(_colorBlue.rotation) * (256 / 360));
            else
                _colorBlue.value = parseInt((360 - Math.abs(_colorBlue.rotation)) * (256 / 360));
            document.getElementById("labelBlue").innerText = _colorBlue.value.toString();
            _colorBlue.matrix = matrix;
            break;
    }
    e.target.style.backgroundColor = "rgb(" + _colorRed.value + ", " + _colorGreen.value + ", " + _colorBlue.value + ")";
    targetLog.innerText = e.target.style.msTransform;
    eventLog.innerText = "Gesture change";
}

Behandeln weiterer Ereignisse nach Bedarf

Im folgenden Beispiel werden nur die anderen hier aufgeführten Ereignisse behandelt. Eine stabilere App würde weitere Funktionalität bieten.

// Tap gesture handler: Display event.
// The touch language described in Touch interaction design (https://go.microsoft.com/fwlink/?LinkID=268162),
// specifies that the tap gesture should invoke an elements primary action (such as launching an application 
// or executing a command). 
// The primary action in this sample (color mixing) is performed through the rotation gesture.
function onMSGestureTap(e) {
    eventLog.innerText = "Gesture tap";
}

// Gesture end handler: Display event.
function onMSGestureEnd(e) {
    if (e.target === this) {
        this.style.borderStyle = "solid";
    }
    eventLog.innerText = "Gesture end";
}

// Hold gesture handler: Display event.
function onMSGestureHold(e) {
    eventLog.innerText = "Gesture hold";
}

// Pointer up handler: Display event.
function onPointerUp(e) {
    eventLog.innerText = "Pointer up";
}

// Pointer cancel handler: Display event.
function onPointerCancel(e) {
    eventLog.innerText = "Pointer canceled";
}

// Pointer capture lost handler: Display event.
function onLostPointerCapture(e) {
    eventLog.innerText = "Pointer capture lost";
}

Links zu komplexeren Beispielen finden Sie weiter unten unter "Verwandte Themen".

Vollständiges Beispiel

Informationen finden Sie unter DOM-Gesten und -Manipulationen (vollständiger Code).

Zusammenfassung und nächste Schritte

In dieser Schnellstartanleitung haben Sie gelernt, wie einfache Gestikereignissen in Windows Store-Apps mit JavaScript behandelt werden.

Die Erkennung von Basisgesten, kombiniert mit Zeigerereignissen, eignet sich gut für die Kontrolle einfacher Interaktionen wie Translation (Ziehen oder Streifen), Drehung und Skalierung (Zusammendrücken oder Aufziehen).

Informationen zur Behandlung aufwendigerer Interaktionen und zur Bereitstellung einer umfassend angepassten Umgebung für Benutzerinteraktionen finden Sie unter Schnellstart: statische Gesten und Schnellstart: Manipulationsgesten.

Weitere Informationen zur Windows 8-Sprache für die Fingereingabe finden Sie unter Design für Interaktion per Fingereingabe.

Verwandte Themen

Entwickler

Reaktion auf Benutzerinteraktionen

Entwickeln von Windows Store-Apps (JavaScript und HTML)

Schnellstart: Zeiger

Schnellstart: statische Gesten

Schnellstart: Manipulationsgesten

Designer

Design für Interaktion per Toucheingabe