Démarrage rapide : pointeurs (HTML)

[ Cet article est destiné aux développeurs de Windows 8.x et Windows Phone 8.x qui créent des applications Windows Runtime. Si vous développez une application pour Windows 10, voir la Documentation ]

Dans les applications en JavaScript, les interactions tactiles, de souris et de stylo/stylet sont reçues, traitées et gérées comme des entrées de pointeur.

Mises à jour pour Windows 8.1: Dans Windows 8.1, les API d’entrée de pointeur ont fait l’objet de plusieurs mises à jour et améliorations. Pour plus d’informations, voir Modifications apportées aux API pour Windows 8.1.

Si vous débutez dans le développement d’applications en JavaScript: Examinez ces rubriques pour vous familiariser avec les technologies discutées ici.

Créer votre première application du Windows Store en JavaScript

Feuille de route pour les applications du Windows Store en JavaScript

Découvrir les événements avec Démarrage rapide : ajout de contrôles HTML et gestion des événements

Fonctionnalités d’application de A à Z:

Étudier cette fonctionnalité de façon plus approfondie dans le cadre de notre série Fonctionnalités d’application de A à Z

Interaction utilisateur de A à Z (HTML)

Personnalisation de l’interaction utilisateur de A à Z (HTML)

Recommandations en matière d’expérience utilisateur:

Les bibliothèques de contrôles de plateforme (HTML et XAML) fournissent l’intégralité de l’expérience d’interaction utilisateur de Windows, y compris les interactions standard, les effets physiques animés et le retour visuel. Utilisez ces contrôles intégrés si vous n’avez pas besoin d’une prise en charge d’interaction personnalisée.

Si les contrôles de plateforme ne suffisent pas, les présentes recommandations peuvent vous aider à fournir une expérience d’interaction utilisateur à la fois immersive et cohérente entre les divers modes d’entrée. Ces recommandations sont axées principalement sur l’entrée tactile, mais elles s’appliquent également à l’entrée de pavé tactile, de souris, de clavier et de stylet.

Exemples: Découvrez cette fonctionnalité en action dans nos exemples d’applications.

Exemple de personnalisation de l’interaction utilisateur de A à Z

Exemple de zoom, de panoramique et de défilement HTML

Entrée : exemple de gestion d’événement de pointeur DOM

Entrée : exemple de mouvements instanciables

Entrée : exemple d’entrée manuscrite

Entrée : exemple de manipulations et de mouvements (JavaScript)

Entrée : exemple d’entrée manuscrite simplifiée

Objectif: apprendre à écouter et à gérer les entrées de pointeur.

Prérequis

Nous partons du principe que vous savez créer une application élémentaire en JavaScript qui utilise le modèle Bibliothèque Windows pour JavaScript.

Pour suivre ce didacticiel, vous devez :

Durée de réalisation: 30 minutes.

Instructions

Qu’est-ce qu’une entrée de pointeur ?

Vous pouvez gérer les interactions de l’utilisateur avec votre application indépendamment du type de périphérique d’entrée utilisé en regroupant la souris, le stylo/stylet et le toucher sous la forme d’une entrée de pointeur abstraite.

Un objet pointeur représente un « contact » d’entrée propre et unique (un élément PointerPoint) effectué à partir d’un périphérique d’entrée (tel qu’une souris, un stylo/stylet ou un ou plusieurs doigts). Le système crée un pointeur à détection d’un contact et le détruit lorsque le pointeur quitte la plage de détection ou est annulé. En cas d’utilisation de plusieurs périphériques ou d’entrées tactiles multipoints, chaque contact est considéré comme un pointeur unique.

Un grand nombre d’API d’entrée par pointeur permettent d’intercepter directement les données d’entrée à partir de différents périphériques. La gestion des événements de pointeur peut permettre d’obtenir des informations courantes, telles que l’emplacement et le type de périphérique, et des informations détaillées, telles que la pression et la géométrie du contact. Les applications doivent souvent répondre de différentes façons à différents modes d’entrée. C’est pourquoi des propriétés de périphérique spécifiques telles que le bouton de la souris sur lequel l’utilisateur appuie ou l’utilisation ou non d’une pointe de gomme de stylet, sont également disponibles. Par exemple, il est possible de filtrer les entrées tactiles afin de prendre en charge les interactions telles que le mouvement panoramique et le défilement, tandis que la souris et le stylo/stylet sont généralement plus appropriés pour effectuer des tâches précises comme l’entrée manuscrite et le dessin. Si une différenciation entre les périphériques d’entrée et leurs fonctionnalités est nécessaire dans le cadre de votre application, voir Démarrage rapide : identification des périphériques d’entrée.

Si vous implémentez votre propre prise en charge d’interaction, gardez à l’esprit que les utilisateurs s’attendent à disposer d’une expérience intuitive impliquant une interaction directe avec les éléments d’interface utilisateur de votre application. Nous vous recommandons de modeler vos interactions personnalisées sur les contrôles de l’infrastructure par souci de cohérence et de possibilité de détection. Ne créez des interactions personnalisées que pour répondre à des exigences claires et bien définies, notamment en l’absence d’interactions de base prenant en charge votre scénario.

Création de l’interface utilisateur

Dans le cadre de cet exemple, nous utilisons un rectangle (target) comme objet cible de l’entrée du pointeur. La couleur de la cible change lorsque l’état du pointeur change.

Les détails de chaque pointeur sont affichés dans un bloc de texte flottant qui est adjacent au pointeur et qui suit tous les mouvements du pointeur. Les événements de pointeur spécifiques sont signalés à l’extrémité droite de l’affichage. La capture d’écran suivante illustre l’interface utilisateur pour cet exemple.

Capture d’écran de l’exemple d’interface utilisateur de l’application.

Voici le code HTML correspondant à cet exemple.

Remarque  Applications du Windows Store

<!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>

Remarque  Applications du Windows Phone Store

<!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>

Voici le code CSS (feuilles de style en cascade) correspondant à cet exemple.

Remarque  Les événements de pointeur ne se déclenchent pas au cours d’une interaction de panoramique ou de zoom. Vous pouvez désactiver les mouvements de panoramique et de zoom au niveau d’une région via les propriétés CSS msTouchAction, overflow et -ms-content-zooming.

 

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 */
}

Écoute des événements de pointeur

Dans la plupart des cas, nous vous conseillons d’obtenir les informations sur le pointeur via l’argument d’événement des gestionnaires d’événements de pointeur dans l’infrastructure de langage choisie.

Si l’argument d’événement n’expose pas les détails du pointeur nécessaires à votre application, vous pouvez obtenir l’accès aux données étendues du pointeur à partir de l’argument d’événement via les méthodes getCurrentPoint et getIntermediatePoints ou les propriétés currentPoint et intermediatePoints. Nous vous recommandons d’utiliser les méthodes getCurrentPoint et getIntermediatePoints car vous pouvez spécifier le contexte des données du pointeur.

La capture d’écran suivante illustre la zone cible avec les détails du pointeur de la souris à partir de cet exemple.

Capture d’écran de la zone cible du pointeur.

Nous configurons ici l’emplacement d’affichage et les détecteurs d’événements de la zone cible.

Dans un premier temps, les variables globales sont déclarées, les zones de cible et de détails de pointeur initialisées et le journal des événements identifié.

// 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();
}

L’objet cible est ensuite configuré et les divers détecteurs d’événements de pointeur relatifs à la cible sont déclarés.

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);
}

Enfin, la zone des détails de pointeur est configurée.

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);
}

Gestion des événements de pointeur

Nous allons maintenant utiliser le retour d’interface utilisateur dans le cadre de la démonstration des gestionnaires d’événements de pointeur de base.

  • Ce gestionnaire gère un événement de contact de pointeur (appuyé, enfoncé). L’événement est ajouté au journal des événements, le pointeur est ajouté au tableau de pointeurs utilisé pour le suivi des pointeurs d’intérêt et les détails de pointeur sont affichés.

    Remarque  Les événements pointerdown et pointerup ne se produisent pas toujours ensemble. L’application doit écouter et gérer tout événement susceptible de conclure une action de pointeur appuyé (tel que pointerup, pointerout, pointercancel et 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);
    }
    
  • Ce gestionnaire gère un événement d’entrée (survol) de pointeur pour un pointeur en contact et déplacé dans la limite de la cible. L’événement est ajouté au journal des événements, le pointeur est ajouté au tableau de pointeurs et les détails de pointeur sont affichés.

    Consultez l’événement pointermove pour la gestion de l’état de survol d’un pointeur qui n’est pas en contact mais qui se trouve dans la limite de la cible (généralement un stylet).

    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);
    }
    
  • Ce gestionnaire gère un événement de déplacement de pointeur. Nous ajoutons l’événement au journal des événements et nous mettons à jour les détails du pointeur (pour le survol, nous ajoutons également le pointeur au tableau de pointeurs).

    MSPointerHover est déconseillé dans Windows 8.1. Utilisez pointermove et la propriété de pointeur IsInContact pour déterminer l’état de survol.

    Remarque   Plusieurs clics de souris simultanés sont également traités dans ce gestionnaire. L’entrée de la souris est associée à un seul pointeur affecté lors de la première détection de l’entrée de la souris. Le fait de cliquer sur un bouton de la souris (gauche, roulette ou droit) pendant l’interaction crée des associations secondaires entre ces boutons et le pointeur via l’événement de pression du pointeur. L’événement de relâchement du pointeur est déclenché uniquement lorsque le dernier bouton de la souris associé à l’interaction (pas nécessairement le bouton d’origine) est relâché. En raison de cette association exclusive, les autres clics de bouton de la souris sont routés via l’événement de déplacement de pointeur.

     

     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);
     }
    
  • Ce gestionnaire gère un événement de roulette de souris (rotation). L’événement est ajouté au journal des événements, le pointeur est ajouté au tableau de pointeurs (si nécessaire) et les détails de pointeur sont affichés.

    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);
    }
    
  • Ce gestionnaire gère un événement de départ (levée) de pointeur. L’événement est ajouté au journal des événements, le pointeur est supprimé du tableau de pointeurs et les détails de pointeur sont mis à jour.

    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;
        }
    }
    
  • Ce gestionnaire gère un événement de départ (sortie) de pointeur. L’événement est ajouté au journal des événements, le pointeur est supprimé du tableau de pointeurs et les détails de pointeur sont mis à jour.

    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;
                }
            }
        }
    }
    
  • Ce gestionnaire gère un événement d’annulation de pointeur. L’événement est ajouté au journal des événements, le pointeur est supprimé du tableau de pointeurs et les détails de pointeur sont mis à jour.

    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;
                }
            }
        }
    }
    
  • Ce gestionnaire gère un événement de capture de pointeur perdue. L’événement est ajouté au journal des événements, le pointeur est supprimé du tableau de pointeurs et les détails de pointeur sont mis à jour.

    Remarque  lostpointercapture peut se produire au lieu de pointerup. Une perte de capture de pointeur peut survenir en raison d’interactions utilisateur ou lors de la capture par programme d’un autre pointeur ou de la libération de la capture de pointeur en cours.

     

    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;
        }
    }
    

Obtention des propriétés du pointeur

L’infrastructure de langage choisie pour l’application régit le mode d’obtention des propriétés du pointeur. L’objet d’événement de pointeur expose directement de nombreuses propriétés. Comme indiqué précédemment, les informations de pointeur supplémentaires peuvent être obtenues via les méthodes getCurrentPoint et getIntermediatePoints ou les propriétés currentPoint et intermediatePoints de l’argument d’événement. Nous vous recommandons d’utiliser les méthodes getCurrentPoint et getIntermediatePoints car vous pouvez spécifier le contexte des données du pointeur.

Ici, diverses propriétés de pointeur font l’objet d’une requête directement à partir de l’objet d’événement et des propriétés étendues qui sont uniquement disponibles via les objets PointerPoint et PointerPointProperties.

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;
}

Des liens vers des exemples plus complexes sont proposés à la section Rubriques associées, en bas de cette page.

Exemple complet

Voir Code complet des pointeurs.

Récapitulatif et étapes suivantes

Cette rubrique de démarrage rapide vous a permis d’en savoir plus sur les entrées de pointeur dans les applications en JavaScript.

Les événements de pointeur sont utiles dans le cadre de la gestion d’interactions simples (telles que l’appui et le glissement) et d’autres interactions spécifiques aux périphériques (dont les entrées provenant de boutons de souris secondaires, d’une molette de souris, d’un bouton de stylet et d’une gomme de stylo).

Pour gérer des interactions plus élaborées, telles que les mouvements décrits dans le langage tactile de Windows 8, voir Démarrage rapide : manipulations et mouvements DOM, Quickstart: Static gestures, et Quickstart: Manipulation gestures.

Pour plus d’informations sur le langage tactile de Windows 8, voir Conception de l’interaction tactile.

Rubriques associées

Développeurs

Réponse à l’interaction utilisateur

Développement d’applications du Windows Store (JavaScript et HTML)

Démarrage rapide : manipulations et mouvements DOM

Démarrage rapide : actions statiques

Démarrage rapide : actions de manipulation

Concepteurs

Conception de l’interaction tactile