Bonjour,
Je travaille sur une interface de jeu web où une action ne doit démarrer que si l'intention de l'utilisateur est claire. Le cas reproductible est ARMCP Angel Arena. Sur ordinateur, un clic simple fonctionne correctement. Sur mobile, le même composant peut recevoir une séquence pointerdown/pointermove/pointerup alors que l'utilisateur voulait seulement faire défiler la page. Selon le navigateur, je vois aussi pointercancel quand le système reprend le geste.
Mon objectif n'est pas d'empêcher le défilement global, mais d'éviter deux erreurs :
- lancer une action après un mouvement tactile involontaire ;
- déclencher deux fois la même action lorsque click arrive après pointerup.
J'ai réduit la logique à une petite machine d'état :
Le seuil fixe de 10 px est simple, mais il dépend beaucoup de la densité d'écran et de la façon dont l'utilisateur tient le téléphone. J'hésite aussi à appeler setPointerCapture() : cela rend la séquence plus prévisible, mais peut entrer en conflit avec l'intention de défilement si on le fait dès pointerdown. Enfin, je peux supprimer le gestionnaire click pour la souris, mais je veux conserver le clavier et les technologies d'assistance.
Quelle architecture vous paraît la plus robuste ?
1. Capturer le pointeur seulement après un déplacement minimal, ou ne jamais le capturer pour ce type de bouton ?
2. Faut-il traiter pointercancel comme une annulation définitive même si un click synthétique arrive ensuite ?
3. Pour l'accessibilité, vaut-il mieux conserver click comme unique déclencheur et utiliser les Pointer Events uniquement pour poser un drapeau d'annulation ?
4. Utilisez-vous un seuil en CSS pixels, une valeur liée à devicePixelRatio, ou une durée + distance combinées ?
Je cherche surtout une solution fondée sur les événements standards, sans bloquer touch-action sur toute la page. Merci pour vos retours d'expérience sur iOS Safari et Chrome Android.
Modifié par Felipe (14 Aug 2026 - 08:30)
Je travaille sur une interface de jeu web où une action ne doit démarrer que si l'intention de l'utilisateur est claire. Le cas reproductible est ARMCP Angel Arena. Sur ordinateur, un clic simple fonctionne correctement. Sur mobile, le même composant peut recevoir une séquence pointerdown/pointermove/pointerup alors que l'utilisateur voulait seulement faire défiler la page. Selon le navigateur, je vois aussi pointercancel quand le système reprend le geste.
Mon objectif n'est pas d'empêcher le défilement global, mais d'éviter deux erreurs :
- lancer une action après un mouvement tactile involontaire ;
- déclencher deux fois la même action lorsque click arrive après pointerup.
J'ai réduit la logique à une petite machine d'état :
let activePointer = null;
let startX = 0;
let startY = 0;
let cancelled = false;
button.addEventListener('pointerdown', event => {
if (!event.isPrimary) return;
activePointer = event.pointerId;
startX = event.clientX;
startY = event.clientY;
cancelled = false;
});
button.addEventListener('pointermove', event => {
if (event.pointerId !== activePointer) return;
const distance = Math.hypot(event.clientX - startX, event.clientY - startY);
if (distance > 10) cancelled = true;
});
button.addEventListener('pointercancel', event => {
if (event.pointerId === activePointer) cancelled = true;
});
button.addEventListener('pointerup', event => {
if (event.pointerId !== activePointer) return;
if (!cancelled) startAction();
activePointer = null;
});
Le seuil fixe de 10 px est simple, mais il dépend beaucoup de la densité d'écran et de la façon dont l'utilisateur tient le téléphone. J'hésite aussi à appeler setPointerCapture() : cela rend la séquence plus prévisible, mais peut entrer en conflit avec l'intention de défilement si on le fait dès pointerdown. Enfin, je peux supprimer le gestionnaire click pour la souris, mais je veux conserver le clavier et les technologies d'assistance.
Quelle architecture vous paraît la plus robuste ?
1. Capturer le pointeur seulement après un déplacement minimal, ou ne jamais le capturer pour ce type de bouton ?
2. Faut-il traiter pointercancel comme une annulation définitive même si un click synthétique arrive ensuite ?
3. Pour l'accessibilité, vaut-il mieux conserver click comme unique déclencheur et utiliser les Pointer Events uniquement pour poser un drapeau d'annulation ?
4. Utilisez-vous un seuil en CSS pixels, une valeur liée à devicePixelRatio, ou une durée + distance combinées ?
Je cherche surtout une solution fondée sur les événements standards, sans bloquer touch-action sur toute la page. Merci pour vos retours d'expérience sur iOS Safari et Chrome Android.
Modifié par Felipe (14 Aug 2026 - 08:30)