web-dev-qa-db-fra.com

Désactiver le défilement lorsque vous touchez au déplacement de certains éléments

J'ai une page avec une section dans laquelle esquisser un dessin. Mais les événements tactiles, du moins ceux qui sont verticaux, font également défiler la page (ce qui dégrade l'expérience de l'esquisse) lors de son utilisation sur un navigateur mobile. Existe-t-il un moyen de: a) désactiver et réactiver le défilement de la page (pour que je puisse la désactiver au démarrage de chaque ligne, mais la réactiver après chaque opération terminée), ou b) désactiver le traitement par défaut de Les événements touchmove (et vraisemblablement le défilement) qui vont sur la toile dans laquelle l'esquisse est dessinée (je ne peux pas les désactiver complètement, car l'esquisse les utilise)?

J'ai utilisé des gestionnaires de souris jquery-mobile vmouse pour l'esquisse, si cela fait une différence.

Mise à jour: Sur un iPhone, si je sélectionne le canevas à esquisser ou si je tiens le doigt un peu avant de dessiner, la page ne défile pas et rien à cause de ce que j'ai codé dans le page.

52
Scott Hunter

Définissez la propriété CSS touch-action sur none, qui fonctionne même avec écouteurs d'événements passifs :

touch-action: none;

L'application de cette propriété à un élément ne déclenchera pas le comportement par défaut (défilement) lorsque l'événement provient de cet élément .

57
John Weisz

Remarque: Comme indiqué dans les commentaires de @nevf, cette solution risque de ne plus fonctionner (du moins sous Chrome) en raison de modifications des performances . La recommandation est d'utiliser touch-action qui est également suggéré par @ JohnWeisz réponse .

Semblable à la réponse donnée par @Llepwryd, j’ai utilisé une combinaison de ontouchstart et ontouchmove pour empêcher le défilement lorsqu’il se trouve sur un certain élément.

Tiré tel quel d'un de mes projets:

window.blockMenuHeaderScroll = false;
$(window).on('touchstart', function(e)
{
    if ($(e.target).closest('#mobileMenuHeader').length == 1)
    {
        blockMenuHeaderScroll = true;
    }
});
$(window).on('touchend', function()
{
    blockMenuHeaderScroll = false;
});
$(window).on('touchmove', function(e)
{
    if (blockMenuHeaderScroll)
    {
        e.preventDefault();
    }
});

Essentiellement, ce que je fais est d’écouter au toucher pour voir s’il commence sur un élément qui est un enfant d’un autre en utilisant jQuery .closest et permettant d’activer/désactiver le mouvement tactile en faisant défiler. Le e.target fait référence à l'élément par lequel commence le début tactile.

Vous souhaitez empêcher l'événement de déplacement tactile par défaut, mais vous devez également effacer l'indicateur correspondant à la fin de l'événement tactile, sinon aucun événement de défilement tactile ne fonctionnera.

Cela peut être accompli sans jQuery, mais pour mon utilisation, j’avais déjà jQuery et je n’avais pas besoin de coder quelque chose pour déterminer si l’élément avait un parent particulier.

Testé dans Chrome sur Android et un iPod Touch à partir du 2013-06-18

41
Turnerj

Il y a un petit "hack" sur CSS qui vous permet également de désactiver le défilement:

.lock-screen {
    height: 100%;
    overflow: hidden;
    width: 100%;
    position: fixed;
}

Ajouter cette classe au corps empêchera le défilement.

21
Mehdi
document.addEventListener('touchstart', function(e) {e.preventDefault()}, false);
document.addEventListener('touchmove', function(e) {e.preventDefault()}, false);

Cela devrait empêcher le défilement, mais également interrompre d'autres événements tactiles, à moins que vous ne définissiez une méthode personnalisée pour les gérer.

18
user1720624

La solution ultime serait de mettre overflow: hidden; sur document.documentElement ainsi:

/* element is an HTML element You want catch the touch */
element.addEventListener('touchstart', function(e) {
    document.documentElement.style.overflow = 'hidden';
});

document.addEventListener('touchend', function(e) {
    document.documentElement.style.overflow = 'auto';
});

En mettant overflow: hidden au début du toucher, tout ce qui dépasse de la fenêtre est masqué, ce qui supprime la possibilité de tout faire défiler (aucun contenu à faire défiler).

Après touchend, le verrou peut être libéré en définissant overflow sur auto (valeur par défaut).

Il vaut mieux annexer ceci à <html> car <body> peut être utilisé pour certains styles, mais il peut aussi amener les enfants à se comporter de manière inattendue.

EDIT: à propos de touch-action: none; _ Safari ne le prend pas en charge selon MDN .

1
soanvig

essayez le débordement caché sur la chose que vous ne voulez pas faire défiler pendant qu'un événement tactile se produit. Par exemple, définissez le débordement masqué sur Démarrer et réglez-le sur Auto on End.

L'avez-vous essayé ? Je serais intéressé de savoir si cela fonctionnerait.

document.addEventListener('ontouchstart', function(e) {
    document.body.style.overflow = "hidden";
}, false);

document.addEventListener('ontouchmove', function(e) {
    document.body.style.overflow = "auto";
}, false);
0
Woody