2 votes

Traiter le balayage court comme un clic

J'ai une application web mobile, qui utilise beaucoup de click les gestionnaires d'événements sur les boutons, etc. Tout cela fonctionne très bien si l'utilisateur "clique" réellement (c'est-à-dire "touchdown-touchup") sur le bouton. Cependant, si l'utilisateur fait un bref glissement, alors l'événement click ne se déclenche pas. Mes utilisateurs se plaignent souvent que l'application n'enregistre pas les clics/taps et que les autres applications fonctionnent correctement.

Bien sûr, je peux obtenir des coordonnées de la touche en ontouchstart y ontouchend et calcule la distance - mais je dois aussi savoir si cette distance est inférieure au maximum que le navigateur traiterait comme un "clic". Je fais no vous voulez passer à l'utilisation d'événements de démarrage/touche au lieu du clic.

J'avais l'habitude d'utiliser la bibliothèque fastclick.js pour gérer les clics/taps dans le passé, mais j'utilise maintenant les événements "clics" natifs avec touch-action: manipulation . Existe-t-il un moyen de spécifier/contrôler le mouvement maximum du doigt sur le bouton qui est toujours enregistré comme un "clic" ?

Mise à jour sur la base des commentaires. L'application est très volumineuse et comporte des centaines, voire des milliers, d'affectations de gestionnaires d'événements (l'application a été développée au cours des huit dernières années). Il n'est pas pratique de les modifier tous, c'est pourquoi je cherche une solution qui me permettrait soit de définir le seuil une fois de manière globale, soit de résoudre le problème avec des gestionnaires de début et de fin de contact de type global.

1voto

gforce301 Points 2063

J'ai pensé que c'était un problème intéressant et j'ai essayé de le résoudre pour vous. D'une certaine manière, c'est un peu similaire au problème d'empêcher une click lorsqu'un dblclick arrive.

L'utilisation d'un seuil de distance pour un "swipe court" me semble, du moins à moi, problématique dans la mesure où la distance seuil pourrait dépendre du système. Au lieu de cela, j'ai décidé de déclencher si l'événement "clic" se produit réellement. J'ai utilisé mousedown comme un simulateur touchstart y mouseup comme un simulateur touchend . mouseup se produit toujours avant click il est donc similaire à touchend à cet égard.

Normalement, si vous "cliquez" ( mousedown ) sur un élément, puis déplacez le pointeur de votre souris hors de l'élément, la fonction click l'événement ne se produit pas. Cela ressemble beaucoup à la situation que vous décrivez comme étant un "coup court". Après une certaine distance, le click l'événement ne se produit pas. Le code ci-dessous enverra un click pour le bouton, même si vous faites un clic droit dessus, que vous enlevez le pointeur et que vous faites un clic gauche. Je pense que cela résoudrait le problème si vous l'utilisiez pour touchstart y touchend au lieu de

// The pre-exisiting click handler
function handleClick(ev) {
    console.log('button clicked. do work.');
}

document.getElementById('theButton').addEventListener('click', handleClick);

// our global "touch" handlers
var touchHandler = {
    curPending: null,
    curElem: null,

    handleTouch: function handleTouch(ev) {
        switch (ev.type) {
            case 'mousedown':
                // capture the target that the click is being initiated on
                touchHandler.curElem = ev.target;

                // add an extra click handler so we know if the click event happens
                ev.target.addEventListener('click', touchHandler.specialClick);
                break;

            case 'mouseup':
                // start a pending click timer in case the click event doesn't happen
                touchHandler.curPending = setTimeout(touchHandler.pendingClick, 1);
                break;
        }
    },

    specialClick: function(ev) {
        // the click event happened 
        // clear our extra handler 
        touchHandler.curElem.removeEventListener('click', touchHandler.specialClick);

        // make sure we don't send an extra click event
        clearTimeout(touchHandler.curPending);
    },

    pendingClick: function() {
        // we never heard the click event

        // clear our extra handler 
        touchHandler.curElem.removeEventListener('click', touchHandler.specialClick);

        // trigger a click event on the element that started it all
        touchHandler.curElem.click();
    }
};

// using "mousedown" as "touchstart" and "mouseup" as "touchend"
document.addEventListener('mouseup', touchHandler.handleTouch);
document.addEventListener('mousedown', touchHandler.handleTouch);

<p>I work when clicked normally but I also work when 
mousedown, drag pointer off me, mouseup</p>
<button id="theButton">Click Me</button>

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X