Schnellstart: Zeiger (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]

Toucheingabe-, Maus- und Zeichen-/Eingabestift-Interaktionen werden in Apps, die JavaScript verwenden, als Zeigereingaben erfasst, verarbeitet und verwaltet.

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 Windows Store-App mit JavaScript

Roadmap für Windows Store-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 Windows-Benutzerinteraktionen, u. a. für Standardinteraktionen, animierte Physikeffekte 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

Eingabe: Freihandbeispiel

Eingabe: Beispiel für Manipulationen und Gesten (JavaScript)

Eingabe: Vereinfachtes Freihandbeispiel

Ziel: Sie erfahren hier, wie Sie auf Zeigereingaben lauschen und diese behandeln.

Voraussetzungen

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.

Anweisungen

Was ist eine Zeigereingabe?

Indem Maus-, Zeichen-/Eingabestift- und Toucheingaben zu abstrakten Zeigereingaben zusammengefasst werden, ist es Ihnen möglich, Benutzerinteraktionen mit Ihrer App unabhängig von der Art des jeweils verwendeten Eingabegeräts zu behandeln.

Ein Zeigerobjekt stellt einen einzelnen, eindeutigen "Eingabekontakt" (ein PointerPoint-Objekt) eines Eingabegeräts (wie Maus, Zeichen-/Eingabestift, ein oder mehrere Finger) dar. Das System erstellt einen Zeiger, wenn ein Kontakt erstmalig festgestellt wird, und zerstört ihn, wenn der Zeiger den Erkennungsbereich verlässt oder abgebrochen wird. Bei Verwendung mehrerer Geräte oder der Mehrfingereingabe wird jeder Kontakt als separater Zeiger behandelt.

Es gibt eine große Anzahl von zeigerbasierten Eingabe-APIs, die Eingabedaten von verschiedenen Geräten direkt abfangen können. Durch die Behandlung von Zeigerereignissen können Sie allgemeine Informationen wie Position und Gerätetyp sowie erweiterte Informationen wie Druck und Kontaktgeometrie erfassen. Da es in vielen Fällen notwendig ist, dass Apps auf verschiedene Eingabemodi unterschiedlich reagieren, stehen außerdem bestimmte gerätespezifische Eigenschaften zur Verfügung, die beispielsweise angeben, welche Maustaste gedrückt wurde oder ob ein Benutzer die Radiergummispitze des Zeichenstifts verwendet. So können beispielsweise Toucheingaben gefiltert werden, sodass sie Interaktionen wie Verschiebungen und Bildlauf unterstützen, während Eingaben mit Maus und Zeichen-/Eingabestift in der Regel für präzisere Aufgaben wie Freihandeingaben und Zeichnen besser geeignet sind. Wenn die App zwischen Eingabegeräten und ihren Funktionen unterscheiden muss, finden Sie entsprechende Informationen unter Schnellstart: Erkennen von Eingabegeräten.

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 auf der Basis der Frameworksteuerelemente zu modellieren, um auf diese Weise für eine konsistente und intuitive Benutzerumgebung zu sorgen. 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 Zeigereingaben verwendet. Die Farbe des Ziels ändert sich, wenn sich der Zeigerstatus ändert.

Details zu jedem Zeiger werden in einem schwebenden Textblock angezeigt, der sich neben dem Zeiger befindet und den Zeigerbewegungen folgt. Spezielle Zeigerereignisse werden ganz rechts angezeigt. Im folgenden Screenshot ist die UI für dieses Beispiel dargestellt.

Screenshot der UI der Beispiel-App

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

Hinweis  Windows Store-Apps

<!DOCTYPE html>
<html>
<head>
    <meta charset="utf-8" />
    <title>PointerInput_Universal.Windows</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>

    <!-- PointerInput_Universal.Windows references -->
    <link href="/css/default.css" rel="stylesheet" />
    <script src="/js/default.js"></script>
</head>
<body class="windows">
    <div id="grid">
        <div id="targetContainer">
            <div id="target"></div>
        </div>
        <div id="bottom">
        </div>
        <div id="eventLog"></div>
    </div>
</body>
</html>

Hinweis  Windows Phone Store-Apps

<!DOCTYPE html>
<html>
<head>
    <meta charset="utf-8" />
    <title>PointerInput_Universal.WindowsPhone</title>

    <!-- WinJS references -->
    <!-- At runtime, ui-themed.css resolves to ui-themed.light.css or ui-themed.dark.css 
    based on the user’s theme setting. This is part of the MRT resource loading functionality. -->
    <link href="/css/ui-themed.css" rel="stylesheet" />
    <script src="//Microsoft.Phone.WinJS.2.1/js/base.js"></script>
    <script src="//Microsoft.Phone.WinJS.2.1/js/ui.js"></script>

    <!-- PointerInput_Universal.Phone references -->
    <link href="/css/default.css" rel="stylesheet" />
    <script src="/js/default.js"></script>
</head>
<body class="phone">
    <div id="grid">
        <div id="targetContainer">
            <div id="target"></div>
        </div>
        <div id="bottom">
        </div>
        <div id="eventLog"></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;
}

#grid {
    display: -ms-grid;
    height: 100vh; /* 100% of viewport height */
    -ms-grid-columns: 4fr 1fr; /* 2 columns */
    -ms-grid-rows: 1fr 320px 1fr;  /* 3 rows */
    /*touch-action: none;*/ /* Disable panning and zooming */
}
#targetContainer {
    border:solid;
    border-width:thin;
    border-color: red;
    -ms-grid-row: 2;
    -ms-grid-column: 1;
    -ms-grid-row-align: center;
    -ms-grid-column-align: center;
    /*touch-action: none; /* Disable panning and zooming */*/
}
#eventLog {
    -ms-grid-row: 1;
    -ms-grid-column: 2; 
    -ms-grid-row-span: 3;
    padding-right: 10px;
    background-color: black;
    color: white;
}
.phone #target {
    width: 200px;
    height: 300px;
    border: none;
    padding: 0px;
    margin: 0px;
    -ms-transform-origin: 0% 0%;
    /*touch-action: none; /* Disable panning and zooming */*/
}
.windows #target {
    width: 400px;
    height: 200px;
    border: none;
    padding: 0px;
    margin: 0px;
    -ms-transform-origin: 0% 0%;
    touch-action: none; /* Disable panning and zooming */
}

Lauschen auf Zeigerereignisse

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.

Im folgenden Screenshot ist der Zielbereich aus diesem Beispiel mit Mauszeigerdetails dargestellt.

Screenshot des Zeigerzielbereichs.

Hier richten wir die Bildschirmposition und Ereignislistener für den Zielbereich ein.

Zuerst werden globale Variablen deklariert, das Ziel und Zeigerdetailbereiche initialisiert und die Ereignisprotokollierung angegeben.

// For this example, we track simultaneous contacts in case the 
// number of contacts has reached the maximum supported by the device.
// Depending on the device, additional contacts might be ignored 
// (PointerPressed not fired). 
var numActiveContacts = 0;

// The input target.
var target;

// Target background colors corresponding to various pointer states.
var pointerColor = {
    hover: "rgb(255, 255, 102)",
    down: "rgb(0, 255, 0)",
    up: "rgb(255, 0, 0)",
    cancel: "rgb(0,0,0)",
    out: "rgb(127,127,127)",
    over: "rgb(0,0,255)"
};

// The event log (updated on each event).
var eventLog;

function initialize() {
    /// <summary>Set up the app.</summary>
    eventLog = document.getElementById("eventLog");
    target = document.getElementById("target");
    setTarget();
}

Anschließend wird das Zielobjekt eingerichtet, und die verschiedenen Zeigerereignislistener für das Ziel werden deklariert.

function setTarget() {
    /// <summary>Set up the target and interaction event handlers.</summary>

    // Initial color of target.
    target.style.backgroundColor = pointerColor.out;

    // Expando dictionary property to track active contacts. 
    // An entry is added during pointer down/hover/over events 
    // and removed during pointer up/cancel/out/lostpointercapture events.
    target.pointers = [];

    // Declare pointer event handlers.
    target.addEventListener("pointerdown", onPointerDown, true);
    target.addEventListener("pointerover", onPointerOver, true);
    target.addEventListener("pointerup", onPointerUp, true);
    target.addEventListener("pointerout", onPointerOut, true);
    target.addEventListener("pointercancel", onPointerCancel, true);
    target.addEventListener("lostpointercapture", onLostPointerCapture, true);
    target.addEventListener("pointermove", onPointerMove, true);
    target.addEventListener("wheel", onMouseWheel, false);
}

Abschließend wird der Zeigerdetailbereich eingerichtet.

function createInfoPop(e) {
    /// <summary>
    /// Create and insert DIV into the DOM for displaying pointer details.
    /// </summary>
    /// <param name="e" type="Event">The event argument.</param>
    var infoPop = document.createElement("div");
    infoPop.setAttribute("id", "infoPop" + e.pointerId);

    // Set screen position of DIV.
    var transform = (new MSCSSMatrix()).translate(e.offsetX + 20, e.offsetY + 20);
    infoPop.style.msTransform = transform;
    target.appendChild(infoPop);

    infoPop.innerText = queryPointer(e);
}

function updateInfoPop(e) {
    /// <summary>
    /// Update pointer details in UI.
    /// </summary>
    /// <param name="e" type="Event">The event argument.</param>
    var infoPop = document.getElementById("infoPop" + e.pointerId);
    if (infoPop === null)
        return;

    // Set screen position of DIV.
    var transform = (new MSCSSMatrix()).translate(e.offsetX + 20, e.offsetY + 20);
    infoPop.style.msTransform = transform;
    infoPop.innerText = queryPointer(e);
}

Behandeln von Zeigerereignissen

Im nächsten Schritt wird UI-Feedback verwendet, um die Verwendung einfacher Zeigerereignishandler zu veranschaulichen.

  • Der folgende Handler kontrolliert ein Zeigerkontaktereignis (nach unten, gedrückt). Das Ereignis wird zum Ereignisprotokoll hinzugefügt, der Zeiger wird zum Zeigerarray hinzugefügt, das zum Verfolgen der relevanten Zeiger verwendet wird, und die Zeigerdetails werden angezeigt.

    Hinweis  Die Ereignisse pointerdown und pointerup treten nicht immer paarweise auf. Die App sollte auf jedes Ereignis lauschen und dieses behandeln, das eine Zeiger-nach-unten-Aktion beenden könnte (beispielsweise pointerup, pointerout, pointercancel und lostpointercapture).

     

    function onPointerDown(e) {
        /// <summary>
        /// Occurs for mouse when at least one mouse button is pressed or 
        /// for touch and pen when there is physical contact with the digitizer.
        /// For input devices that do not support hover, the pointerover event is 
        /// fired immediately before the pointerdown event.  
        /// Here, we  filter pointer input based on the first pointer type detected. 
        /// </summary>
        /// <param name="e" type="Event">The event argument.</param>
    
        // pointerdown and pointerup events do not always occur in pairs. 
        // Listen for and handle any event that might conclude a pointer down action 
        // (such as pointerup, pointerout, pointercancel, and lostpointercapture).
        //
        // For this example, we track the number of contacts in case the 
        // number of contacts has reached the maximum supported by the device.
        // Depending on the device, additional contacts might be ignored 
        // (PointerPressed not fired). 
    
        // Prevent the next handler in the hierarchy from receiving the event.
        e.cancelBubble = true;
    
        // Check if the number of supported contacts is exceeded.
        var touchCapabilities = new Windows.Devices.Input.TouchCapabilities();
        if ((touchCapabilities.touchPresent != 0) & (numActiveContacts > touchCapabilities.contacts)) {
            return;
        }
    
        // Update event details and target UI.
        eventLog.innerText += "\nDown: " + e.pointerId;
        target.style.backgroundColor = pointerColor.down;
    
        // Check if pointer already exists (if hover/over occurred prior to down).
        for (var i in target.pointers) {
            if (target.pointers[i].id = e.pointerId) {
                return;
            }
        }
    
        // Push new pointer Id onto expando target pointers array.
        target.pointers.push({ id: e.pointerId, type: e.pointerType });
    
        // Ensure that the element continues to receive PointerEvents 
        // even if the contact moves off the element. 
        // Capturing the current pointer can improve usability by reducing 
        // the touch precision required when interacting with an element.
        // Note: Only the assigned pointer is affected. 
        target.setPointerCapture(e.pointerId);
    
        // Display pointer details.
        createInfoPop(e);
    }
    
  • Dieser Handler dient der Verwaltung eines Zeigereintrittsereignisses (über dem Ziel) für einen Zeiger, der Kontakt hat und innerhalb der Grenzen des Ziels bewegt wird. Das Ereignis wird zum Ereignisprotokoll hinzugefügt, der Zeiger wird zum Zeigerarray hinzugefügt, und die Zeigerdetails werden angezeigt.

    Informationen zum Verarbeiten des Zeigezustands eines Zeigers, der keinen Kontakt hat, aber innerhalb der Grenze des Ziels liegt (normalerweise ein Zeichen-/Eingabestift), finden Sie unter dem pointermove-Ereignis.

    function onPointerOver(e) {
        /// <summary>
        /// Occurs when a pointer is detected within the hit test boundaries 
        /// of an element.
        /// Also occurs prior to a pointerdown event for devices that do not 
        /// support hover.  
        /// This event type is similar to pointerenter, but bubbles. 
        /// See the pointermove event for handling the hover state of a pointer 
        /// that is not in contact but is within the boundary of the target 
        /// (typically a pen/stylus device). 
        /// </summary>
        /// <param name="e" type="Event">The event argument.</param>
    
        // Prevent the next handler in the hierarchy from receiving the event.
        e.cancelBubble = true;
    
        // Update event details and target UI.
        eventLog.innerText += "\nOver: " + e.pointerId;
    
        if (target.pointers.length === 0) {
            // Change background color of target when pointer contact detected.
            if (e.getCurrentPoint(e.currentTarget).isInContact) {
                // Pointer down occured outside target.
                target.style.backgroundColor = pointerColor.down;
            } else {
                // Pointer down occured inside target.
                target.style.backgroundColor = pointerColor.over;
            }
        }
    
        // Check if pointer already exists.
        for (var i in target.pointers) {
            if (target.pointers[i].id = e.pointerId) {
                return;
            }
        }
    
        // Push new pointer Id onto expando target pointers array.
        target.pointers.push({ id: e.pointerId, type: e.pointerType });
    
        // Ensure that the element continues to receive PointerEvents 
        // even if the contact moves off the element. 
        // Capturing the current pointer can improve usability by reducing 
        // the touch precision required when interacting with an element.
        // Note: Only the assigned pointer is affected. 
        target.setPointerCapture(e.pointerId);
    
        // Display pointer details.
        createInfoPop(e);
    }
    
  • Der folgende Handler kontrolliert ein Zeigerbewegungsereignis. Wir fügen das Ereignis dem Ereignisprotokoll hinzu und aktualisieren die Zeigerdetails (für das Zeigen fügen wir den Zeiger außerdem dem Zeigerarray hinzu).

    MSPointerHover gilt in Windows 8.1 als veraltet. Verwenden Sie pointermove und die Zeigereigenschaft IsInContact, um den Zeigezustand zu bestimmen.

    Hinweis   Mehrere gleichzeitige Klicks auf Maustasten werden ebenfalls in diesem Handler verarbeitet. Die Mauseingabe wird einem einzelnen Zeiger zugeordnet, der bei der ersten Ermittlung einer Mauseingabe zugewiesen wird. Klicks auf weitere Maustasten (links, Rad oder rechts) während der Interaktion erstellt sekundäre Zuordnungen zwischen diesen Tasten und dem Zeiger mit dem PointerPressed-Ereignis. Das PointerReleased-Ereignis wird nur ausgelöst, wenn die letzte Maustaste, die der Interaktion zugeordnet wurde (nicht unbedingt die erste Taste), losgelassen wird. Aufgrund dieser exklusiven Zuordnung werden Klicks auf andere Maustasten über das Zeigerbewegungsereignis geleitet.

     

     function onPointerMove(e) {
         /// <summary>
         /// Occurs when a pointer moves within the hit test boundaries 
         /// of an element.
         /// </summary>
         /// <param name="e" type="Event">The event argument.</param>
    
         // NOTE: Multiple, simultaneous mouse button inputs are processed here.
         // Mouse input is associated with a single pointer assigned when 
         // mouse input is first detected. 
         // Clicking additional mouse buttons (left, wheel, or right) during 
         // the interaction creates secondary associations between those buttons 
         // and the pointer through the pointer pressed event. 
         // The pointer released event is fired only when the last mouse button 
         // associated with the interaction (not necessarily the initial button) 
         // is released. 
         // Because of this exclusive association, other mouse button clicks are 
         // routed through the pointer move event.  
    
         // Prevent the next handler in the hierarchy from receiving the event.
         e.cancelBubble = true;
    
         if (e.pointerType == "mouse") {
             // Mouse button states are extended PointerPoint properties.
             var pt = e.getCurrentPoint(e.currentTarget);
             var ptProperties = pt.properties;
             if (ptProperties.isLeftButtonPressed) {
                 eventLog.innerText += "\nLeft button: " + e.pointerId;
             }
             if (ptProperties.isMiddleButtonPressed) {
                 eventLog.innerText += "\nWheel button: " + e.pointerId;
             }
             if (ptProperties.isRightButtonPressed) {
                 eventLog.innerText += "\nRight button: " + e.pointerId;
             }
         }
         // Handle hover state of a pointer that is not in contact but is within 
         // the boundary of the target (typically a pen/stylus device). 
         if (e.pointerType == "pen") {
             var pt = e.getCurrentPoint(e.currentTarget);
             if (pt.isInContact == false) {
                 // Update event details and target UI.
                 target.style.backgroundColor = pointerColor.hover;
                 eventLog.innerText = "\nHover: " + e.pointerId;
    
                 // Check if pointer already exists.
                 for (var i in target.pointers) {
                     if (target.pointers[i].id = e.pointerId) {
                         updateInfoPop(e);
                         return;
                     }
                 }
    
                 target.pointers.push({ id: e.pointerId, type: e.pointerType });
    
                 // Ensure that the element continues to receive PointerEvents 
                 // even if the contact moves off the element. 
                 // Capturing the current pointer can improve usability by reducing 
                 // the touch precision required when interacting with an element.
                 // Note: Only the assigned pointer is affected. 
                 target.setPointerCapture(e.pointerId);
             }
         }
    
         // Display pointer details.
         updateInfoPop(e);
     }
    
  • Dieser Handler behandelt ein Mausradereignis (Drehung). Wir fügen das Ereignis dem Ereignisprotokoll hinzu, fügen den Zeiger dem Zeigerarray hinzu (sofern erforderlich) und zeigen die Zeigerdetails an.

    function onMouseWheel(e) {
        /// <summary>  
        /// Occurs when the mouse wheel is rotated. 
        /// </summary> 
        /// <param name="e" type="Event">The event argument.</param>
        // Check if a mouse pointer already exists.
        for (var i in target.pointers) {
            // Ensure existing pointer type registered with pointerover is mouse. 
            if (target.pointers[i].type === "mouse") {
                e.pointerId = target.pointers[i].id;
                break;
            }
        }
        eventLog.innerText += "\nMouse wheel: " + e.pointerId;
        // For this example, we fire a corresponding pointer down event.
        onPointerDown(e);
    }
    
  • Der folgende Handler kontrolliert ein Zeigeraustrittsereignis (nach oben). Das Ereignis wird zum Ereignisprotokoll hinzugefügt, der Zeiger wird aus dem Zeigerarray entfernt, und die Zeigerdetails werden aktualisiert.

    function onPointerUp(e) {
        /// <summary>
        /// Occurs for mouse at transition from at least one button pressed 
        /// to no buttons pressed.
        /// Occurs for touch and pen when contact is removed from the digitizer. 
        /// For input devices that do not support hover, the pointerout event 
        /// is fired immediately after the pointerup event.  
        /// </summary>
        /// <param name="e" type="Event">The event argument.</param>
    
        // Prevent the next handler in the hierarchy from receiving the event.
        e.cancelBubble = true;
    
        // Update event details.
        eventLog.innerText += "\nUp: " + e.pointerId;
    
        // If event source is mouse pointer and the pointer is still 
        // over the target, retain pointer and pointer details.
        // Return without removing pointer from pointers dictionary.
        // For this example, we assume a maximum of one mouse pointer.
        if ((e.pointerType === "mouse") &
            (document.elementFromPoint(e.x, e.y) === target)) {
            target.style.backgroundColor = pointerColor.up;
            return;
        }
    
        // Ensure capture is released on a pointer up event.
        target.releasePointerCapture(e.pointerId);
    
        // Remove pointer from pointers dictionary.
        var targetPointers = target.pointers;
        for (var i in targetPointers) {
            if (target.pointers[i].id === e.pointerId) {
                target.pointers.splice(i, 1);
                var pointerInfoPop = document.getElementById("infoPop" + e.pointerId);
                if (pointerInfoPop === null)
                    return;
                pointerInfoPop.removeNode(true);
            }
        }
    
        // Update target UI.
        if (target.pointers.length === 0) {
            target.style.backgroundColor = pointerColor.up;
        }
    }
    
  • Der folgende Handler kontrolliert ein Zeigeraustrittsereignis (aus dem Ziel). Das Ereignis wird zum Ereignisprotokoll hinzugefügt, der Zeiger wird aus dem Zeigerarray entfernt, und die Zeigerdetails werden aktualisiert.

    function onPointerOut(e) {
        /// <summary>
        /// Occurs when a pointer (in contact or not) moves out of the 
        /// target hit test boundary, after a pointerup event for a device 
        /// that does not support hover, and after a pointercancel event. 
        /// This event type is similar to pointerleave, but bubbles.  
        /// Note: Pointer capture is maintained until pointer up event.
        /// </summary>
        /// <param name="e" type="Event">The event argument.</param>
    
        // Prevent the next handler in the hierarchy from receiving the event.
        e.cancelBubble = true;
    
        // Update event details.
        eventLog.innerText += "\nPointer out: " + e.pointerId;
    
        // Remove pointer from pointers dictionary.
        var targetPointers = target.pointers;
        for (var i in targetPointers) {
            if (target.pointers[i].id === e.pointerId) {
                target.pointers.splice(i, 1);
                var pointerInfoPop = document.getElementById("infoPop" + e.pointerId);
                if (pointerInfoPop === null)
                    return;
                pointerInfoPop.removeNode(true);
    
                // Update target UI.
                if (target.pointers.length === 0) {
                    target.style.backgroundColor = pointerColor.out;
                }
            }
        }
    }
    
  • Der folgende Handler kontrolliert ein Zeigerabbruchereignis. Das Ereignis wird zum Ereignisprotokoll hinzugefügt, der Zeiger wird aus dem Zeigerarray entfernt, und die Zeigerdetails werden aktualisiert.

    function onPointerCancel(e) {
        /// <summary>
        /// Occurs when a pointer is removed.
        /// The app will not receive subsequent events for that pointer, including pointerup.  
        /// </summary>
        /// <param name="e" type="Event">The event argument.</param>
    
        // A pointer can be canceled as a result of one of the following:
        //    - A touch contact is canceled when a pen is detected.
        //    - More than 100ms has passed since the device reported
        //      an active contact.
        //    - The desktop is locked or the user logged off. 
        //    - The number of simultaneous contacts exceeds the number 
        //      supported by the device.
        //    - The system has determined that a pointer is unlikely to 
        //      continue to produce events (for example, due to a hardware event).
        //    - After a pointerdown event, the pointer is subsequently used to 
        //      manipulate the page viewport (for example, panning or zooming).  
    
        // Prevent the next handler in the hierarchy from receiving the event.
        e.cancelBubble = true;
    
        // Update event details.
        eventLog.innerText += "\nPointer canceled: " + e.pointerId;
    
        // Ensure capture is released on a pointer cancel event.
        target.releasePointerCapture(e.pointerId);
    
        // Update target UI.
        if (target.pointers.length === 0) {
            target.style.backgroundColor = pointerColor.cancel;
        }
    
        // Remove pointer from pointers dictionary.
        var targetPointers = target.pointers;
        for (var i in targetPointers) {
            if (target.pointers[i].id === e.pointerId) {
                target.pointers.splice(i, 1);
                var pointerInfoPop = document.getElementById("infoPop" + e.pointerId);
                if (pointerInfoPop === null)
                    return;
                pointerInfoPop.removeNode(true);
    
                // Update target UI.
                if (target.pointers.length === 0) {
                    target.style.backgroundColor = pointerColor.out;
                }
            }
        }
    }
    
  • Der folgende Handler kontrolliert ein Ereignis für eine getrennte Zeigererfassung. Das Ereignis wird zum Ereignisprotokoll hinzugefügt, der Zeiger wird aus dem Zeigerarray entfernt, und die Zeigerdetails werden aktualisiert.

    Hinweis  lostpointercapture kann anstelle von pointerup eintreten. Die Zeigererfassung kann durch Benutzerinteraktionen, die programmseitige Erfassung eines anderen Zeigers oder das absichtliche Freigeben der aktuellen Zeigererfassung getrennt werden.

     

    function onLostPointerCapture(e) {
        /// <summary>
        /// Occurs after pointer capture is released for the pointer.  
        /// </summary>
        /// <param name="e" type="Event">The event argument.</param>
    
        // lostpointercapture can fire instead of pointerup. 
    
        // Pointer capture can be lost as a result of one of the following:
        //    - User interactions
        //    - Programmatic caputre of another pointer
        //    - Captured pointer was deliberately released
    
        // Prevent the next handler in the hierarchy from receiving the event.
        e.cancelBubble = true;
    
        // Update event details.
        eventLog.innerText += "\nLost pointer capture: " + e.pointerId;
    
        // We need the device type to handle lost pointer capture from mouse input.
        // Use the getCurrentPoint method over currentPoint property to ensure
        // the coordinate space is in relation to the target element.
        // Note: getCurrentPoint and currentPoint are only available in the 
        // local compartment, they are not available in the web compartment.
        var ptTarget = e.getCurrentPoint(e.currentTarget);
        var ptContainer = e.getCurrentPoint(document.getElementsByTagName("body")[0]);
    
        // If event source is mouse pointer and the pointer is still over 
        // the target, retain pointer and pointer details.
        // For this example, we assume only one mouse pointer.
        if ((ptTarget.pointerDevice.pointerDeviceType === Windows.Devices.Input.PointerDeviceType.mouse) &
            (document.elementFromPoint(ptContainer.position.x, ptContainer.position.y) === target)) {
            target.setPointerCapture(e.pointerId);
            return;
        }
    
        // Remove pointer from pointers dictionary.
        var targetPointers = target.pointers;
        for (var i in targetPointers) {
            if (target.pointers[i].id === e.pointerId) {
                target.pointers.splice(i, 1);
                var pointerInfoPop = document.getElementById("infoPop" + e.pointerId);
                if (pointerInfoPop === null)
                    return;
                pointerInfoPop.removeNode(true);
            }
        }
    
        // Update target UI.
        if (target.pointers.length === 0) {
            target.style.backgroundColor = pointerColor.cancel;
        }
    }
    

Abrufen von Zeigereigenschaften

Das Sprachframework, das Sie für Ihre App verwenden, schreibt vor, wie Zeigereigenschaften abgerufen werden. Viele Eigenschaften werden direkt über das Zeigerereignisobjekt verfügbar gemacht. Wie bereits erwähnt können zusätzliche Zeigerinformationen mit den Methoden getCurrentPoint und getIntermediatePoints oder den Eigenschaften currentPoint und intermediatePoints des Ereignisarguments abgerufen werden. Wir empfehlen die Verwendung der Methoden getCurrentPoint und getIntermediatePoints, weil sie die Möglichkeit bieten, den Kontext der Zeigerdaten anzugeben.

Hier fragen wir verschiedene Zeigereigenschaften direkt vom Ereignisobjekt sowie erweiterte Eigenschaften ab, die nur über PointerPoint- und PointerPointProperties-Objekte verfügbar sind.

function queryPointer(e) {
    /// <summary>
    /// Get extended pointer data.
    /// </summary>
    /// <param name="e" type="Event">The event argument.</param>

    // We get the extended pointer info through the getCurrentPoint method
    // of the event argument. (We recommend using getCurrentPoint 
    // to ensure the coordinate space is in relation to the target.)
    // Note: getCurrentPoint and currentPoint are only available in the 
    // local compartment, they are not available in the web compartment.

    var pt = e.getCurrentPoint(e.currentTarget);
    var ptTargetProperties = pt.properties;

    var details = "Pointer Id: " + e.pointerId;
    switch (e.pointerType) {
        case "mouse":
            details += "\nPointer type: mouse";
            details += "\nLeft button: " + ptTargetProperties.isLeftButtonPressed;
            details += "\nRight button: " + ptTargetProperties.isRightButtonPressed;
            details += "\nWheel button: " + ptTargetProperties.isMiddleButtonPressed;
            details += "\nX1 button: " + ptTargetProperties.isXButton1Pressed;
            details += "\nX2 button: " + ptTargetProperties.isXButton2Pressed;
            break;
        case "pen":
            details += "\nPointer type: pen";
            if (pt.isInContact) {
                details += "\nPressure: " + ptTargetProperties.pressure;
                details += "\nrotation: " + ptTargetProperties.rotation;
                details += "\nTilt X: " + ptTargetProperties.xtilt;
                details += "\nTilt Y: " + ptTargetProperties.ytilt;
                details += "\nBarrel button pressed: " + ptTargetProperties.isBarrelButtonPressed;
            }
            break;
        case "touch":
            details += "\nPointer type: touch";
            details += "\nPressure: " + ptTargetProperties.pressure;
            details += "\nrotation: " + ptTargetProperties.rotation;
            details += "\nTilt X: " + ptTargetProperties.xtilt;
            details += "\nTilt Y: " + ptTargetProperties.ytilt;
            break;
        default:
            details += "\nPointer type: " + "n/a";
            break;
    }
    details += "\nPointer location (target): " + e.offsetX + ", " + e.offsetY;
    details += "\nPointer location (screen): " + e.screenX + ", " + e.screenY;

    return details;
}

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

Vollständiges Beispiel

Siehe Zeiger (vollständiger Code).

Zusammenfassung und nächste Schritte

In dieser Schnellstartanleitung haben Sie Zeigereingaben in Apps mit JavaScript kennengelernt.

Zeigerereignisse sind hilfreich, um einfacher Interaktionen wie Tippen und Ziehen und andere gerätespezifische Interaktionen wie Eingaben über sekundäre Maustasten, Mausrad, Zeichenstift-Drucktaste und Radiergummispitze zu kontrollieren.

Informationen zur Behandlung aufwendigerer Interaktionen, z. B. der Gesten, die in der Windows 8-Sprache für die Toucheingabe beschrieben werden, finden Sie unter Schnellstart: DOM-Gesten und -Manipulationen, Schnellstart: statische Gesten und Schnellstart: Manipulationsgesten.

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

Verwandte Themen

Entwickler

Reaktion auf Benutzerinteraktionen

Entwickeln von Windows Store-Apps (JavaScript und HTML)

Schnellstart: DOM-Gesten und -Manipulationen

Schnellstart: Statische Gesten

Schnellstart: Manipulationsgesten

Designer

Design für Interaktion per Toucheingabe