Guida introduttiva: Puntatori (HTML)

[ Questo articolo è rivolto agli sviluppatori per Windows 8.x e Windows Phone 8.x che realizzano app di Windows Runtime. Gli sviluppatori che usano Windows 10 possono vedere Documentazione aggiornata ]

Nelle app che usano JavaScript le interazioni tramite tocco, mouse e penna/stilo vengono ricevute, elaborate e gestite come input del puntatore.

Aggiornamenti per Windows 8.1: In Windows 8.1 vengono introdotti diversi aggiornamenti e miglioramenti alle API di input tramite puntatore. Per altre informazioni, vedi Modifiche delle API per Windows 8.1.

Se non hai familiarità con lo sviluppo di app mediante JavaScript,: ti consigliamo di leggere gli argomenti seguenti per scoprire di più sulle tecnologie descritte in questa guida.

Creare la prima app di Windows Store in JavaScript

Roadmap per app di Windows Store scritte in JavaScript

Informazioni sugli eventi sono disponibili in Guida introduttiva: Aggiunta di controlli HTML e gestione degli eventi

Funzionalità delle app dall'inizio alla fine:

Per conoscere meglio questa funzionalità, vedi gli argomenti della serie Funzionalità dell'app dall'inizio alla fine

Interazioni con l'utente, dall'inizio alla fine (HTML)

Personalizzazione delle interazioni con l'utente, dall'inizio alla fine (HTML)

Linee guida per l'esperienza utente:

Le raccolte di controlli della piattaforma (HTML e XAML) forniscono l'esperienza di interazione utente Windows completa, oltre a interazioni standard, effetti fisici animati e feedback visivo. Se non hai l'esigenza di supportare interazioni personalizzate, usa questi controlli predefiniti.

Se i controlli della piattaforma non sono sufficienti, queste linee guida ti aiuteranno a offrire un'esperienza di interazione coinvolgente e Immersive coerente tra le diverse modalità di input. Queste linee guida sono incentrate principalmente sull'input tocco, ma sono rilevanti anche per input di tipo tocco, mouse, tastiera e stilo.

Esempi: Per esaminare questa funzionalità in azione, vedi gli esempi di app.

Personalizzazione delle interazioni con l'utente, dall'inizio alla fine

Esempio di controlli HTML di scorrimento, panoramica e zoom

Input: Esempio di gestione degli eventi relativi al puntatore DOM

Input: Esempio di gesti istanziabili

Input: Esempio di input penna

Input: Esempio di manipolazioni e gesti (JavaScript)

Input: Esempio di input penna semplificato

Obiettivo: Informazioni su come ascoltare e gestire l'input del puntatore.

Prerequisiti

In questa guida introduttiva si suppone che tu sia in grado di creare con Javascript un'app di base che usi il modello Libreria Windows per JavaScript.

Per completare questa esercitazione, devi:

Tempo per il completamento: 30 minuti.

Istruzioni

Che cos'è l'input del puntatore?

Unificando l'input mouse, penna/stilo e tocco come input del puntatore astratto, puoi gestire le interazioni degli utenti con la tua app indipendentemente dal tipo di dispositivo di input in uso.

Un oggetto puntatore rappresenta un singolo "contatto" di input univoco (PointerPoint) ricevuto da un dispositivo di input, ad esempio un mouse, una penna/stilo, un singolo dito o più dita. Il sistema crea un puntatore nel momento in cui rileva un contatto per la prima volta e lo elimina quando il puntatore lascia (si allontana) dall'intervallo di rilevamento o viene annullato. Nel caso di input da più dispositivi o multitouch, ogni contatto viene considerato un puntatore univoco.

Esiste un ampio set di API di input basate su puntatore in grado di intercettare dati di input direttamente da diversi dispositivi. Puoi gestire gli eventi relativi al puntatore per ottenere informazioni di base, ad esempio posizione e tipo di dispositivo, oltre a informazioni avanzate quali pressione e geometria del contatto. Poiché nella maggior parte dei casi le app devono rispondere a modalità di input diverse in modi diversi, sono disponibili anche le proprietà del dispositivo specifiche, ad esempio il pulsante del mouse premuto da un utente o l'eventuale uso della punta della penna per cancellare. Ad esempio, il tocco può essere filtrato per supportare interazioni quali le panoramiche e lo scorrimento mentre mouse e penne/stilo sono in genere più adatti ad attività di precisione quali l'input penna e il disegno. Se la tua app deve distinguere i diversi dispositivi di input e le relative funzionalità, vedi Guida introduttiva: Identificazione dei dispositivi di input.

Se implementi un supporto personalizzato per tocco e interazioni tieni presente che gli utenti si aspettano un'esperienza intuitiva che include l'interazione diretta con gli elementi della tua app. Ti consigliamo di modellare le tue interazioni personalizzate sui controlli del framework per garantire la coerenza e l'intuitività. Crea interazioni personalizzate solo in presenza di un requisito chiaro e ben definito e le interazioni di base non sono in grado di supportare il tuo scenario.

Creare l'interfaccia utente

Per questo esempio, usiamo un rettangolo (target) come oggetto di destinazione per l'input del puntatore. Il colore della destinazione cambia quando varia lo stato del puntatore.

I dettagli di ogni puntatore sono visualizzati all'interno di un blocco di testo mobile situato accanto al puntatore, di cui segue ogni spostamento. Gli eventi specifici del puntatore sono segnalati sul lato destro dello schermo. Nella cattura di schermata seguente viene illustrata l'interfaccia utente per l'esempio.

Cattura di schermata dell'interfaccia utente dell'app di esempio.

HTML per questo esempio.

Nota  App di 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>

Nota  App di 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>

CSS (Cascading Style Sheets) per questo esempio.

Nota  Gli eventi puntatore non vengono generati durante un'interazione di tipo panoramica o zoom. Puoi disabilitare la panoramica e lo zoom in un'area tramite le proprietà CSS msTouchAction, overflow e -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 */
}

Ascoltare gli eventi puntatore

Nella maggior parte dei casi è consigliabile ottenere informazioni sul puntatore mediante l'argomento dell'evento del gestore eventi del puntatore nel framework del linguaggio che hai scelto.

Se l'argomento dell'evento non espone i dettagli del puntatore richiesti dall'app, puoi ottenere l'accesso a dati del puntatore estesi dall'argomento dell'evento tramite i metodi getCurrentPoint e getIntermediatePoints o le proprietà currentPoint e intermediatePoints. Ti consigliamo di usare i metodi getCurrentPoint e getIntermediatePoints perché puoi specificare il contesto dei dati del puntatore.

Nelle catture di schermata seguenti viene illustrata l'area di destinazione con i dettagli sul puntatore del mouse di questo esempio.

Schermata dell'area di destinazione del puntatore.

Qui impostiamo i listener della posizione sullo schermo e degli eventi per l'area di destinazione.

Per prima cosa, dichiariamo le variabili globali, inizializziamo la destinazione e le aree dei dettagli del puntatore e identifichiamo il registratore degli eventi.

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

Successivamente, impostiamo l'oggetto di destinazione e dichiariamo i vari listener di eventi puntatore per la destinazione.

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

Infine, impostiamo l'area dei dettagli del puntatore

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

Gestire gli eventi relativi al puntatore

Usiamo quindi il feedback dell'interfaccia utente per mostrare i gestori di eventi del puntatore di base.

  • Questo gestore gestisce un evento di contatto (giù, premuto) del puntatore. Aggiungiamo l'evento al registro degli eventi, aggiungiamo il puntatore alla matrice di puntatori usata per il tracciamento dei puntatori di interesse e visualizziamo i dettagli del puntatore.

    Nota  Non sempre gli eventi pointerdown e pointerup si verificano contemporaneamente. L'app deve ascoltare e gestire qualsiasi evento che potrebbe indicare la conclusione di un'azione di puntatore giù (ad esempio pointerup, pointerout, pointercancel e 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);
    }
    
  • Questo gestore gestisce un evento di ingresso (sopra) per un puntatore che è a contatto e viene spostato entro il limite della destinazione. Aggiungiamo l'evento al registro degli eventi, aggiungiamo il puntatore alla matrice di puntatori e visualizziamo i dettagli del puntatore.

    Vedi l'evento pointermove per la gestione dello stato di selezione di un puntatore che non è a contatto, ma è compreso nei limiti della destinazione (in genere un dispositivo di tipo penna/stilo).

    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);
    }
    
  • Questo gestore gestisce un evento di spostamento del puntatore. Aggiungiamo l'evento al registro degli eventi e aggiorniamo i dettagli del puntatore (per la selezione aggiungiamo anche il puntatore alla matrice di puntatori).

    MSPointerHover è deprecato in Windows 8.1. Per determinare lo stato di selezione, usa le proprietà del puntatore pointermove e IsInContact.

    Nota   In questo gestore vengono inoltre elaborati più clic del pulsante del mouse simultanei. L'input del mouse è associato a un singolo puntatore assegnato la prima volta che l'input in questione viene rilevato. Se si fa clic su altri pulsanti del mouse (sinistro, rotellina o destro) durante l'interazione, vengono create associazioni secondarie tra questi pulsanti e il puntatore tramite l'evento di pressione del puntatore. L'evento di rilascio del puntatore viene generato solo quando viene rilasciato l'ultimo pulsante del mouse associato all'interazione. Non si tratta necessariamente del pulsante iniziale. A causa di questa associazione esclusiva, altri clic con un pulsante del mouse vengono instradati attraverso l'evento di spostamento del puntatore.

     

     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);
     }
    
  • Questo gestore gestisce un evento di rotellina del mouse (rotazione). Aggiungiamo l'evento al registro degli eventi, aggiungiamo il puntatore alla matrice di puntatori, se necessario, e visualizziamo i dettagli del puntatore.

    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);
    }
    
  • Questo gestore gestisce un evento di allontanamento (verso l'alto) del puntatore. Aggiungiamo l'evento al registro degli eventi, rimuoviamo il puntatore dalla matrice di puntatori e aggiorniamo i dettagli del puntatore.

    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;
        }
    }
    
  • Questo gestore gestisce un evento di allontanamento (all'esterno) del puntatore. Aggiungiamo l'evento al registro degli eventi, rimuoviamo il puntatore dalla matrice di puntatori e aggiorniamo i dettagli del puntatore.

    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;
                }
            }
        }
    }
    
  • Questo gestore gestisce un evento di annullamento del puntatore. Aggiungiamo l'evento al registro degli eventi, rimuoviamo il puntatore dalla matrice di puntatori e aggiorniamo i dettagli del puntatore.

    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;
                }
            }
        }
    }
    
  • Questo gestore gestisce un evento di acquisizione del puntatore persa. Aggiungiamo l'evento al registro degli eventi, rimuoviamo il puntatore dalla matrice di puntatori e aggiorniamo i dettagli del puntatore.

    Nota  lostpointercapture può verificarsi al posto di pointerup. L'acquisizione del puntatore può venire persa a causa delle interazioni utente, perché è stato acquisito un altro puntatore a livello di programmazione o perché il puntatore corrente è stato volutamente rilasciato.

     

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

Recuperare le proprietà del puntatore

Il framework del linguaggio che scegli per la tua app determina il modo in cui recuperi le proprietà del puntatore. Molte proprietà vengono esposte direttamente mediante l'oggetto evento puntatore. Come accennato in precedenza, è possibile ottenere altre informazioni sul puntatore tramite i metodi getCurrentPoint e getIntermediatePointso le proprietà currentPoint e intermediatePoints dell'argomento dell'evento. Ti consigliamo di usare i metodi getCurrentPoint e getIntermediatePoints perché puoi specificare il contesto dei dati del puntatore.

Ora eseguiamo una query sulle varie proprietà del puntatore direttamente dall'oggetto evento e dalle proprietà estese disponibili solo tramite gli oggetti PointerPoint e 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;
}

Per i link a esempi più complessi, vedi gli Argomenti correlati alla fine della pagina.

Esempio completo

Vedi Codice completo per i puntatori.

Riepilogo e passaggi successivi

In questa Guida introduttiva hai imparato i concetti relativi all'input del puntatore nelle app che usano JavaScript.

Gli eventi del puntatore sono utili per la gestione di interazioni semplici, ad esempio tocco, scorrimento e altre interazioni specifiche del dispositivo, incluso l'input dai pulsanti del mouse secondari, dalla rotellina del mouse, dal pulsante della penna e dalla punta della penna per cancellare.

Per la gestione di interazioni più elaborate, come i gesti descritti nel linguaggio per il tocco di Windows 8, vedi Guida introduttiva: Gesti e manipolazioni DOM, Guida introduttiva: Gesti statici e Guida introduttiva: Gesti di manipolazione.

Per altre informazioni sul linguaggio per il tocco di Windows 8, vedi Progettazione delle interazioni tramite tocco.

Argomenti correlati

Sviluppatori

Risposta alle interazioni degli utenti

Sviluppo di app di Windows Store (JavaScript e HTML)

Guida introduttiva: Gesti e manipolazioni DOM

Guida introduttiva: Gesti statici

Guida introduttiva: Gesti di manipolazione

Designer

Progettazione delle interazioni tramite tocco