J'ai une liste, avec overflow-x
et overflow-y
réglé sur auto
. De plus, j'ai configuré le défilement de momentum, de sorte que le défilement tactile fonctionne bien sur mobile, en utilisant webkit-overflow-scrolling: true
.
Le problème, cependant, est que je ne peux pas comprendre comment désactiver le défilement horizontal lors du défilement vertical. Cela conduit à une très mauvaise expérience utilisateur, car le glissement vers le haut à gauche ou le haut à droite entraînera le défilement de la table en diagonale. Lorsque l'utilisateur fait défiler verticalement, je ne veux absolument PAS de défilement horizontal tant que l'utilisateur n'a pas arrêté de défiler verticalement.
J'ai essayé ce qui suit:
JS:
offsetX: number;
offsetY: number;
isScrollingHorizontally = false;
isScrollingVertically = false;
//Detect the scrolling events
ngOnInit() {
this.scrollListener = this.renderer.listen(
this.taskRows.nativeElement,
'scroll',
evt => {
this.didScroll();
}
);
fromEvent(this.taskRows.nativeElement, 'scroll')
.pipe(
debounceTime(100),
takeUntil(this.destroy$)
)
.subscribe(() => {
this.endScroll();
});
}
didScroll() {
if ((this.taskRows.nativeElement.scrollLeft != this.offsetX) && (!this.isScrollingHorizontally)){
console.log("Scrolling horizontally")
this.isScrollingHorizontally = true;
this.isScrollingVertically = false;
this.changeDetectorRef.markForCheck();
}else if ((this.taskRows.nativeElement.scrollTop != this.offsetY) && (!this.isScrollingVertically)) {
console.log("Scrolling Vertically")
this.isScrollingHorizontally = false;
this.isScrollingVertically = true;
this.changeDetectorRef.markForCheck();
}
}
endScroll() {
console.log("Ended scroll")
this.isScrollingVertically = false;
this.isScrollingHorizontally = false;
this.changeDetectorRef.markForCheck();
}
HTML:
<div
class="cu-dashboard-table__scroll"
[class.cu-dashboard-table__scroll_disable-x]="isScrollingVertically"
[class.cu-dashboard-table__scroll_disable-y]="isScrollingHorizontally"
>
CSS:
&__scroll {
display: flex;
width: 100%;
height: 100%;
overflow-y: auto;
overflow-x: auto;
will-change: transform;
-webkit-overflow-scrolling: touch;
&_disable-x {
overflow-x: hidden;
}
&_disable-y {
overflow-y: hidden;
}
}
Mais à chaque fois que je mets overflow-x
ouoverflow-y
à hidden
quand son défilée, défilante pépin et revenir en arrière vers le haut. J'ai également remarqué que webkit-overflow-scrolling: true
c'est la raison pour laquelle cela se produit, lorsque je le supprime, le comportement semble s'arrêter, mais j'en ai absolument besoin pour le défilement de l'élan sur les appareils mobiles.
Comment désactiver le défilement horizontal lors du défilement vertical?
la source
Réponses:
Essaye ça
Au lieu d'utiliser un div pour le défilement, pourquoi n'en utilisez-vous pas deux? Avoir un pour X et un pour Y
la source
C'est généralement une mauvaise pratique pour votre conception d'avoir besoin d'un défilement multiaxe sur mobile, à moins que vous ne montriez peut-être de grandes tables de données. Cela étant dit, pourquoi voulez-vous l'empêcher? Si un utilisateur veut faire défiler en diagonale, cela ne me semble pas être la fin du monde. Certains navigateurs, comme Chrome sur OSX, font déjà ce que vous décrivez par défaut.
Si vous devez avoir un défilement sur un seul axe, une solution possible pourrait être de suivre vous-même la position de défilement via
touchstart
et lestouchmove
événements. Si vous définissez votre seuil de glissement inférieur à celui du navigateur, vous pourrez peut-être faire vos trucs css avant qu'il ne commence à défiler, en évitant le problème perçu. De plus, même si cela ne fonctionne toujours pas, vous avez le démarrage tactile et l'emplacement actuel du toucher. À partir de ceux-ci, si vous enregistrez la position de défilement de départ de votre div, vous pouvez faire défiler manuellement le div à l'endroit correct pour le contrer en sautant vers le haut si vous le devez. Un algorithme possible pourrait ressembler à ceci:Deuxième idée: dans votre gestionnaire de défilement, au lieu de changer les classes css, définissez la position de défilement de la div directement pour l'axe que vous souhaitez verrouiller. IE, si vous faites défiler horizontalement, définissez toujours scrollTop sur sa valeur de départ. Cela peut également annuler le défilement, pas sûr. Il faudrait l'essayer pour voir si cela fonctionne.
la source
Il existe de nombreuses façons de résoudre ce problème. Quelques bonnes idées vous sont proposées ici.
Cependant, comme d'autres l'ont fait allusion, s'appuyer sur (ou essayer d'éviter) le défilement multidimensionnel est une mauvaise odeur UX - indiquant que l'UX est un problème. Je ne pense pas que ce soit un problème de développement légitime. Il serait préférable de prendre du recul et de réévaluer ce que vous essayez d'accomplir. L'un des problèmes pourrait être que dans un effort pour rendre l'interface utilisateur plus utilisable, vous confondrez les utilisateurs. La convivialité décrite ici provoquerait probablement de la confusion.
Ce sont quelques questions qui peuvent être posées (inaudible).
Si vous essayez de permettre à des informations supplémentaires de la liste de données verticale d'être consultables uniquement lorsque l'utilisateur a sélectionné la ligne, il serait probablement bien préférable d'avoir simplement une liste plate par défaut défilante verticalement et de basculer uniquement la verticale informations lorsque la "ligne" a été sélectionnée / activée. Réduire les détails vous ramènerait à la liste verticale plate.
Si vous devez sauter à travers des cerceaux pour résoudre un tel défi technique, c'est une bonne indication que l'expérience utilisateur n'a pas été bien conçue au départ.
la source
Besoin d'utiliser trois conteneurs.
Dans le premier conteneur, j'active le défilement vertical et interdit l'autorisation horizontale.
Dans le second, vice versa, j'active le défilement horizontal et interdit le vertical. Assurez-vous d'utiliser
overflow-x: hidden;
etoverflow-y: hidden;
, sinon, les conteneurs enfants peuvent dépasser le conteneur actuel.Besoin également d'utiliser
min-width: 100%; min-height: 100%;
.Pour le troisième conteneur, nous devons utiliser
display: inline-block;
, puis le contenu interne étirera ce conteneur et les barres de défilement correspondantes apparaîtront sur les deux blocs parents.HTML
CSS
Vous pouvez le tester ici dans Safari sur iPhone.
Bonne chance!! 😉
la source
ça a l'air amusant;)
Je ne discuterai pas si c'est raisonnable.
Je l'ai essayé avec RxJS:
Nous TAMPON tous les 4
touchemove
événement, puis faire un calcul très sophistiqué avec les coordonnées des quatre événements (map(calculateDirection)
) qui sortiesRIGHT
,LEFT
,UP
ouDOWN
et sur la base que j'essaie de désactiver le défilement vertical ou horicontal. Sur mon téléphone Android en chrome ça marche un peu;)J'ai créé une petite aire de jeux qui pourrait être améliorée, réécrite, que ce soit ...
Bravo Chris
la source