Cette page a été traduite à partir de l'anglais par la communauté. Vous pouvez contribuer en rejoignant la communauté francophone sur MDN Web Docs.

View in English Always switch to English

Évènements de pointeur

Baseline Large disponibilité *

Cette fonctionnalité est bien établie et fonctionne sur de nombreux appareils et versions de navigateurs. Elle est disponible sur tous les navigateurs depuis juillet 2020.

* Certaines parties de cette fonctionnalité peuvent bénéficier de prise en charge variables.

Une grande partie du contenu web actuel suppose que le dispositif de pointage de l'utilisateur·ice est une souris. Cependant, comme de nombreux appareils prennent en charge d'autres types de dispositifs de saisie par pointage, tels qu'un stylo/stylet et des surfaces tactiles, il faut étendre les modèles d'évènements de pointage existants. Les évènements de pointeur répondent à ce besoin.

Les évènements de pointeur sont des évènements DOM déclenchés pour un dispositif de pointage. Ils sont conçus pour créer un modèle unique d'évènements DOM afin de gérer les dispositifs de saisie par pointage comme une souris, un stylo/stylet ou une surface tactile (par exemple un ou plusieurs doigts).

Le pointeur est un dispositif indépendant du matériel qui peut cibler un ensemble précis de coordonnées à l'écran. Un modèle unique d'évènements pour les pointeurs peut simplifier la création de sites web et d'applications et offrir une bonne expérience utilisateur·ice quel que soit le matériel de l'utilisateur·ice. Cependant, lorsque la gestion spécifique à un appareil est souhaitée, les évènements de pointeur définissent une propriété pointerType qui permet d'examiner le type d'appareil ayant produit l'évènement.

Les évènements nécessaires à la gestion d'une saisie générique par pointeur sont analogues aux évènements de souris (mousedown/pointerdown, mousemove/pointermove, etc.). Par conséquent, les types d'évènements de pointeur sont volontairement similaires aux types d'évènements souris.

De plus, un évènement de pointeur contient les propriétés habituelles présentes dans les évènements souris (coordonnées côté client, élément cible, états des boutons, etc.), ainsi que de nouvelles propriétés pour les autres formes de saisie : pression, géométrie du contact, inclinaison, etc. En fait, l'interface PointerEvent hérite de toutes les propriétés de MouseEvent, ce qui facilite la migration du contenu des évènements souris vers les évènements de pointeur.

Terminologie

État des boutons actifs

La condition dans laquelle un pointeur a une valeur non nulle pour la propriété buttons. Par exemple, dans le cas d'un stylo, lorsque le stylo est en contact physique avec le numériseur, ou lorsqu'au moins un bouton est enfoncé pendant le survol.

Pointeur actif

Tout dispositif de saisie pointeur qui peut produire des évènements. Un pointeur est considéré comme actif s'il peut encore produire d'autres évènements. Par exemple, un stylo dans un état abaissé est considéré comme actif, car il peut produire d'autres évènements lorsqu'il est soulevé ou déplacé.

Numériseur

Un dispositif de détection doté d'une surface qui peut détecter un contact. Le plus souvent, il s'agit d'un écran tactile qui peut détecter la saisie provenant d'un dispositif comme un stylo, un stylet ou un doigt. Certains dispositifs de détection peuvent détecter la proximité immédiate du dispositif de saisie, et cet état s'exprime sous la forme d'un survol, comme avec une souris.

Teste de cible

Le processus utilisé par le navigateur pour déterminer un élément cible pour un évènement de pointeur. En général, cette détermination s'effectue en tenant compte de l'emplacement du pointeur ainsi que de la disposition visuelle des éléments d'un document sur un support d'affichage.

Pointeur

Une représentation indépendante du matériel des dispositifs de saisie qui peuvent cibler une coordonnée précise (ou un ensemble de coordonnées) sur un écran. Les dispositifs de saisie pointeur comprennent notamment la souris, le stylo/stylet et les contacts tactiles.

Capture du pointeur

La capture du pointeur permet de rediriger les évènements d'un pointeur vers un élément particulier plutôt que vers le résultat normal du test de cible à l'emplacement du pointeur. Consultez capturer le pointeur pour voir un exemple.

Note : La capture du pointeur est différente du verrouillage du pointeur, qui empêche physiquement le pointeur de quitter une zone.

Évènement de pointeur

Un évènement DOM déclenché pour un pointeur.

Interfaces

L'interface principale est l'interface PointerEvent, qui comprend un constructor, ainsi que plusieurs types d'évènements et les gestionnaires d'évènements globaux associés.

La norme comprend également des extensions aux interfaces Element et Navigator.

Les sous-sections suivantes contiennent de brèves descriptions de chaque interface et propriété.

Interface PointerEvent

L'interface PointerEvent étend l'interface MouseEvent et possède les propriétés suivantes.

altitudeAngle Lecture seule

Représente l'angle entre l'axe d'un transducteur (un pointeur ou un stylet) et le plan X-Y de l'écran d'un appareil.

azimuthAngle Lecture seule

Représente l'angle entre le plan Y-Z et le plan contenant à la fois l'axe du transducteur (un pointeur ou un stylet) et l'axe Y.

PointerEvent.persistentDeviceId Lecture seule

Un identifiant unique du dispositif de pointage qui génère le PointerEvent.

pointerId Lecture seule

Un identifiant unique du pointeur à l'origine de l'évènement.

width Lecture seule

La largeur (mesure sur l'axe X), en pixels CSS, de la géométrie du contact du pointeur.

height Lecture seule

La hauteur (mesure sur l'axe Y), en pixels CSS, de la géométrie du contact du pointeur.

pressure Lecture seule

La pression normalisée de la saisie du pointeur, comprise entre 0 et 1, où 0 et 1 représentent respectivement les pressions minimale et maximale que le matériel peut détecter.

tangentialPressure Lecture seule

La pression tangentielle normalisée de la saisie du pointeur (également appelée pression du barillet ou contrainte du cylindre), comprise entre -1 et 1, où 0 correspond à la position neutre de la commande.

tiltX Lecture seule

L'angle du plan (en degrés, compris entre -90 et 90) entre le plan Y-Z et le plan contenant à la fois l'axe du pointeur (par exemple, celui d'un stylo ou d'un stylet) et l'axe Y.

tiltY Lecture seule

L'angle du plan (en degrés, compris entre -90 et 90) entre le plan X-Z et le plan contenant à la fois l'axe du pointeur (par exemple, celui d'un stylo ou d'un stylet) et l'axe X.

twist Lecture seule

La rotation horaire du pointeur (par exemple, celui d'un stylo ou d'un stylet) autour de son axe principal, en degrés, avec une valeur comprise entre 0 et 359.

pointerType Lecture seule

Indique le type de dispositif à l'origine de l'évènement (souris, stylo, toucher, etc.).

isPrimary Lecture seule

Indique si le pointeur représente le pointeur principal de ce type de pointeur.

Types d'évènements et gestionnaires d'évènements globaux

Les évènements de pointeur possèdent dix types d'évènements, dont sept ont une sémantique similaire à celle de leurs équivalents pour la souris (down, up, move, over, out, enter et leave).

Voici une brève description de chaque type d'évènement.

Évènement Description
pointerover Déclenché lorsqu'un pointeur est déplacé dans les limites du teste de cible d'un élément.
pointerenter Déclenché lorsqu'un pointeur est déplacé dans les limites du teste de cible d'un élément ou de l'un de ses descendants, notamment à la suite d'un évènement pointerdown provenant d'un appareil qui ne prend pas en charge le survol (voir pointerdown).
pointerdown Déclenché lorsqu'un pointeur passe à l'état des boutons actifs.
pointermove Déclenché lorsqu'un pointeur change de coordonnées. Cet évènement est également utilisé si le changement d'état du pointeur ne peut pas être signalé par d'autres évènements.
pointerup Déclenché lorsqu'un pointeur n'est plus dans l'état des boutons actifs.
pointercancel Un navigateur déclenche cet évènement s'il conclut que le pointeur ne peut plus produire d'évènements (par exemple, si l'appareil associé est désactivé ou si le navigateur décide d'interpréter l'interaction comme un panoramique/zoom). Pour savoir comment contrôler ce comportement, consultez la section sur la propriété CSS touch-action ci-dessous.
pointerout Déclenché pour plusieurs raisons notamment : le pointeur est déplacé hors des limites du teste de cible d'un élément ; l'évènement pointerup est déclenché pour un appareil qui ne prend pas en charge le survol (voir pointerup) ; après le déclenchement de l'évènement pointercancel (voir pointercancel) ; lorsqu'un stylo ou un stylet quitte la plage de survol détectable par le numériseur.
pointerleave Déclenché lorsqu'un pointeur est déplacé hors des limites du teste de cible d'un élément. Pour les appareils utilisant un stylo, cet évènement est déclenché lorsque le stylet quitte la plage de survol détectable par le numériseur.
pointerrawupdate Déclenché lorsqu'un pointeur modifie des propriétés qui ne déclenchent pas les évènements pointerdown ou pointerup.
gotpointercapture Déclenché lorsqu'un élément reçoit la capture du pointeur.
lostpointercapture Déclenché après la libération de la capture du pointeur pour un pointeur.

Extensions de Element

Il existe trois extensions de l'interface Element :

hasPointerCapture()

Indique si l'élément sur lequel la méthode est appelée capture le pointeur identifié par l'identifiant de pointeur donné.

releasePointerCapture()

Libère (arrête) la capture du pointeur qui a été définie précédemment pour un évènement de pointeur précis.

setPointerCapture()

Désigne un élément précis comme cible de capture des évènements de pointeur suivants.

Extension de Navigator

La propriété Navigator.maxTouchPoints sert à déterminer le nombre maximal de points de contact simultanés pris en charge à un instant donné.

Exemples

Cette section contient des exemples d'utilisation basique des interfaces d'évènements de pointeur.

Enregistrer des gestionnaires d'évènements

Cet exemple enregistre un gestionnaire pour chaque type d'évènement de l'élément donné.

html
<div id="cible">Touchez-moi…</div>
js
function overHandler(event) {}
function enterHandler(event) {}
function downHandler(event) {}
function moveHandler(event) {}
function upHandler(event) {}
function cancelHandler(event) {}
function outHandler(event) {}
function leaveHandler(event) {}
function rawUpdateHandler(event) {}
function gotCaptureHandler(event) {}
function lostCaptureHandler(event) {}

const el = document.getElementById("cible");
// Enregistre les gestionnaires d'évènements de pointeur
el.onpointerover = overHandler;
el.onpointerenter = enterHandler;
el.onpointerdown = downHandler;
el.onpointermove = moveHandler;
el.onpointerup = upHandler;
el.onpointercancel = cancelHandler;
el.onpointerout = outHandler;
el.onpointerleave = leaveHandler;
el.onpointerrawupdate = rawUpdateHandler;
el.ongotpointercapture = gotCaptureHandler;
el.onlostpointercapture = lostCaptureHandler;

Propriétés des évènements

Cet exemple illustre l'accès à toutes les propriétés d'un évènement de pointeur.

html
<div id="cible">Touchez-moi…</div>
js
const id = -1;

function processId(event) {
  // Traite cet évènement selon son identifiant
}
function processMouse(event) {
  // Traite l'évènement de pointeur de souris
}
function processPen(event) {
  // Traite l'évènement de pointeur de stylo
}
function processTouch(event) {
  // Traite l'évènement de pointeur tactile
}
function processTilt(tiltX, tiltY) {
  // Gestionnaire des données d'inclinaison
}
function processPressure(pressure) {
  // Gestionnaire de la pression
}
function processNonPrimary(event) {
  // Gestionnaire des pointeurs non principaux
}

function downHandler(ev) {
  // Calcule la surface de contact du point tactile
  const area = ev.width * ev.height;

  // Compare l'identifiant mis en cache à celui de cet évènement et le traite en conséquence
  if (id === ev.identifier) processId(ev);

  // Appelle le gestionnaire approprié selon le type de pointeur
  switch (ev.pointerType) {
    case "mouse":
      processMouse(ev);
      break;
    case "pen":
      processPen(ev);
      break;
    case "touch":
      processTouch(ev);
      break;
    default:
      console.log(
        `Le type de pointeur ${ev.pointerType} n'est pas pris en charge`,
      );
  }

  // Appelle le gestionnaire de l'inclinaison
  if (ev.tiltX !== 0 && ev.tiltY !== 0) processTilt(ev.tiltX, ev.tiltY);

  // Appelle le gestionnaire de la pression
  processPressure(ev.pressure);

  // Si cet évènement n'est pas principal, appelle le gestionnaire des pointeurs non principaux
  if (!ev.isPrimary) processNonPrimary(ev);
}

const el = document.getElementById("cible");
// Enregistre le gestionnaire de pointerdown
el.onpointerdown = downHandler;

Déterminer le pointeur principal

Dans certains scénarios, plusieurs pointeurs peuvent être présents (par exemple, un appareil doté à la fois d'un écran tactile et d'une souris), ou un pointeur peut prendre en charge plusieurs points de contact (par exemple, un écran tactile qui prend en charge les contacts de plusieurs doigts). L'application peut utiliser la propriété isPrimary pour identifier un pointeur principal parmi l'ensemble des pointeurs actifs de chaque type de pointeur. Si une application souhaite uniquement prendre en charge un pointeur principal, elle peut ignorer tous les évènements de pointeur qui ne sont pas principaux.

Pour une souris, il n'existe qu'un seul pointeur, qui est donc toujours le pointeur principal. Pour une saisie tactile, un pointeur est considéré comme principal si l'utilisateur·ice touche l'écran alors qu'aucun autre contact tactile n'est actif. Pour une saisie au stylo ou au stylet, un pointeur est considéré comme principal si le stylo de l'utilisateur·ice entre initialement en contact avec l'écran alors qu'aucun autre stylo actif n'est en contact avec l'écran.

Déterminer l'état des boutons

Certains dispositifs de pointage (comme une souris ou un stylo) prennent en charge plusieurs boutons, et les pressions sur les boutons peuvent être combinées (c'est-à-dire lorsqu'un bouton supplémentaire est enfoncé alors qu'un autre bouton du dispositif de pointage est déjà enfoncé).

Pour déterminer l'état des pressions sur les boutons, les évènements de pointeur utilisent les propriétés button et buttons de l'interface MouseEvent, dont PointerEvent hérite.

Le tableau suivant fournit les valeurs de button et buttons pour les différents états des boutons du dispositif.

État des boutons du dispositif button buttons
Ni les boutons ni le contact tactile ou du stylo n'ont changé depuis le dernier évènement -1
Déplacement de la souris sans bouton enfoncé, déplacement du stylo en survol sans bouton enfoncé 0
Souris gauche, contact tactile, contact du stylo 0 1
Bouton central de la souris 1 4
Bouton droit de la souris, bouton du barillet du stylo 2 2
Souris X1 (retour) 3 8
Souris X2 (avance) 4 16
Bouton de gomme du stylo 5 32

Note : La propriété button indique une modification de l'état du bouton. Cependant, comme dans le cas du toucher, lorsque plusieurs évènements se produisent avec un évènement, ils ont tous la même valeur.

Capturer le pointeur

La capture du pointeur permet de rediriger les évènements d'un évènement de pointeur particulier vers un élément particulier au lieu du teste de cible normal à l'emplacement du pointeur. Cela permet de s'assurer qu'un élément continue à recevoir les évènements de pointeur même si le contact du dispositif de pointage quitte l'élément cible (par exemple lors du défilement ou du panoramique).

La capture du pointeur fait que la cible capture tous les évènements de pointeur suivants comme s'ils se produisent au-dessus de la cible de capture. Par conséquent, pointerover, pointerenter, pointerleave et pointerout ne se déclenchent pas tant que cette capture est définie. Pour les navigateurs tactiles qui autorisent la manipulation directe (angl.), une capture implicite du pointeur (angl.) est appelée sur l'élément lorsqu'un évènement pointerdown se déclenche. La capture peut être libérée manuellement en appelant element.releasePointerCapture sur l'élément cible, ou elle est implicitement libérée après un évènement pointerup ou pointercancel.

Note : Si vous devez déplacer un élément dans le DOM, veillez à appeler setPointerCapture() après les déplacements dans le DOM afin que setPointerCapture() ne perde pas sa référence. Par exemple, si vous devez utiliser Element.append() pour déplacer un élément ailleurs, veillez à appeler setPointerCapture() sur cet élément uniquement après l'appel à Element.append().

L'exemple suivant montre comment définir la capture du pointeur sur un élément.

html
<div id="cible">Touchez-moi…</div>
js
function downHandler(ev) {
  const el = document.getElementById("cible");
  // L'élément « cible » reçoit/capture les évènements suivants
  el.setPointerCapture(ev.pointerId);
}

const el = document.getElementById("cible");
el.onpointerdown = downHandler;

L'exemple suivant montre comment libérer la capture du pointeur lorsqu'un évènement pointercancel se produit. Le navigateur le fait automatiquement lorsqu'un évènement pointerup ou pointercancel se produit.

html
<div id="cible">Touchez-moi…</div>
js
function downHandler(ev) {
  const el = document.getElementById("cible");
  // L'élément « cible » reçoit/capture les évènements suivants
  el.setPointerCapture(ev.pointerId);
}

function cancelHandler(ev) {
  const el = document.getElementById("cible");
  // Libère la capture du pointeur
  el.releasePointerCapture(ev.pointerId);
}

const el = document.getElementById("cible");
// Enregistre les gestionnaires de pointerdown et pointercancel
el.onpointerdown = downHandler;
el.onpointercancel = cancelHandler;

La propriété CSS touch-action

La propriété CSS touch-action sert à définir si le navigateur applique ou non son comportement tactile par défaut (natif) (comme le zoom ou le panoramique) à une zone. Cette propriété peut s'appliquer à tous les éléments sauf : les éléments en ligne non remplacés, les lignes de tableau, les groupes de lignes, les colonnes de tableau et les groupes de colonnes.

La valeur auto signifie que le navigateur peut appliquer son comportement tactile par défaut à la zone définie, tandis que la valeur none désactive le comportement tactile par défaut du navigateur pour cette zone. Les valeurs pan-x et pan-y signifient que les contacts qui commencent dans la zone définie servent uniquement au défilement horizontal et vertical, respectivement. La valeur manipulation signifie que le navigateur peut considérer que les contacts qui commencent sur l'élément servent uniquement au défilement et au zoom.

Dans l'exemple suivant, le comportement tactile par défaut est désactivé pour certains éléments button.

css
button#tiny {
  touch-action: none;
}

Dans l'exemple suivant, lorsque l'élément cible est touché, il effectue uniquement un panoramique horizontal.

css
#cible {
  touch-action: pan-x;
}

Compatibilité avec les évènements souris

Bien que les interfaces d'évènements de pointeur permettent aux applications de créer des expériences utilisateur·ice enrichies sur les appareils compatibles avec les pointeurs, la grande majorité du contenu web actuel est conçue pour fonctionner uniquement avec une saisie à la souris. Par conséquent, même si un navigateur prend en charge les évènements de pointeur, il doit continuer à traiter les évènements souris afin que le contenu qui suppose une saisie uniquement à la souris fonctionne sans modification directe. Idéalement, une application compatible avec les pointeurs n'a pas besoin de gérer explicitement la saisie à la souris. Cependant, comme le navigateur doit traiter les évènements souris, certains problèmes de compatibilité peuvent nécessiter une gestion. Cette section contient des informations sur l'interaction entre les évènements de pointeur et les évènements souris, ainsi que sur ses conséquences pour les développeur·euse·s d'applications.

Le navigateur peut associer une saisie générique par pointeur à des évènements souris pour assurer la compatibilité avec le contenu basé sur la souris. Cette association d'évènements est appelée évènements souris de compatibilité. Les auteur·ice·s peuvent empêcher la production de certains évènements souris de compatibilité en annulant l'évènement pointerdown, mais notez que :

  • Les évènements souris peuvent uniquement être empêchés lorsque le pointeur est abaissé.
  • Les pointeurs en survol (par exemple, une souris sans bouton enfoncé) ne peuvent pas voir leurs évènements souris empêchés.
  • Les évènements mouseover, mouseout, mouseenter et mouseleave ne sont jamais empêchés, même lorsque le pointeur est abaissé.

Bonnes pratiques

Voici quelques bonnes pratiques à prendre en compte lors de l'utilisation des évènements de pointeur :

  • Réduisez la quantité de travail effectuée dans les gestionnaires d'évènements.
  • Ajoutez les gestionnaires d'évènements à un élément cible précis, plutôt qu'à l'ensemble du document ou à des nœuds plus élevés dans l'arbre du document.
  • L'élément cible (le nœud) doit être suffisamment grand pour accueillir la plus grande surface de contact, généralement le contact d'un doigt. Si la zone cible est trop petite, la toucher peut déclencher d'autres évènements pour les éléments adjacents.

Spécifications

Spécification
Pointer Events

Compatibilité des navigateurs

Certaines valeurs supplémentaires ont été définies pour la propriété CSS touch-action dans le cadre de la spécification des évènements de pointeur (angl.), mais ces valeurs bénéficient actuellement d'une prise en charge limitée dans les implémentations.

Voir aussi