Eu tenho uma lista, com overflow-x
oe overflow-y
definido como auto
. Além disso, configurei a rolagem de momento, para que a rolagem por toque funcione bem no celular, usando webkit-overflow-scrolling: true
.
O problema, no entanto, é que não consigo descobrir como desativar a rolagem horizontal ao rolar verticalmente. Isso leva a uma péssima experiência do usuário, pois o deslizar para o canto superior esquerdo ou o canto superior direito fará com que a tabela role na diagonal. Quando o usuário está rolando verticalmente, NÃO quero absolutamente nenhuma rolagem horizontal até que o usuário pare de rolar verticalmente.
Eu tentei o seguinte:
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;
}
}
Mas a cada vez que eu jogo overflow-x
ou overflow-y
para hidden
quando o seu foi rolado, rolando vai pulso aleatório e saltar de volta ao topo. Também notei que webkit-overflow-scrolling: true
é a razão pela qual isso ocorre. Quando removo, o comportamento parece parar, mas eu absolutamente preciso disso para a rolagem de momento em dispositivos móveis.
Como desabilito a rolagem horizontal ao rolar verticalmente?
fonte
Respostas:
Tente isto
Em vez de usar uma div para rolar, por que você não usa duas? Tenha um para X e um para Y
fonte
Geralmente, é uma prática ruim para o seu projeto precisar de rolagem multiaxis no celular, a menos que você esteja mostrando grandes tabelas de dados. Dito isto, por que você quer impedi-lo? Se um usuário quiser rolar na diagonal, isso não parece o fim do mundo para mim. Alguns navegadores, como o Chrome no OSX, já fazem o que você está descrevendo por padrão.
Se você precisar ter a rolagem de eixo único, uma solução possível pode ser acompanhar a posição da rolagem por meio de
touchstart
etouchmove
eventos. Se você definir seu limite de arrasto mais baixo que o do navegador, poderá fazer suas coisas em CSS antes que ele comece a rolar, evitando a falha percebida. Além disso, mesmo se ele ainda apresentar falhas, você terá o toque inicial e a localização atual do toque. Nestas, se você gravar a posição de rolagem inicial do seu div, poderá rolar manualmente o div para o local correto para neutralizá-lo pulando para o topo se necessário. Um possível algoritmo pode ser assim:Segunda ideia: no seu manipulador de rolagem, em vez de alterar as classes css, defina a posição de rolagem da div diretamente para o eixo que você deseja bloquear. IE, se você estiver rolando horizontalmente, sempre defina o scrollTop como seu valor inicial. Isso também pode cancelar a rolagem, não tenho certeza. Você precisaria tentar para ver se funciona.
fonte
Existem várias maneiras de tentar resolver isso. Algumas boas idéias são oferecidas aqui.
No entanto, como outros aludiram, contar com (ou tentar evitar) a rolagem multidimensional é um mau cheiro de UX - indicativo de que o UX é um problema. Eu não acho que isso seja uma questão legítima para desenvolvedores. Seria melhor dar um passo atrás e reavaliar o que você está tentando realizar. Um dos problemas pode ser que, em um esforço para tornar a interface do usuário mais utilizável, você confunda os usuários. A usabilidade descrita aqui provavelmente causaria confusão.
Estas são algumas perguntas que podem ser feitas (inaudíveis).
Se você estiver tentando permitir que informações adicionais da lista de dados verticais sejam navegáveis somente quando o usuário selecionou a linha, provavelmente seria muito melhor simplesmente ter uma lista simples por padrão, apenas rolável na vertical e alternar apenas a vertical informações quando a "linha" foi selecionada / ativada. Recolher os detalhes levaria você de volta à lista vertical plana.
Se você estiver tendo que passar por obstáculos para resolver um desafio técnico tão marginal, é uma boa indicação de que a experiência do usuário não foi bem projetada para começar.
fonte
Precisa usar três recipientes.
No primeiro contêiner, habilito a rolagem vertical e desabilito a horizontal.
No segundo, vice-versa, habilito a rolagem horizontal e desaprovo a vertical. Certifique-se de usar
overflow-x: hidden;
eoverflow-y: hidden;
, caso contrário, os contêineres filhos podem ir além do contêiner atual.Também precisa usar
min-width: 100%; min-height: 100%;
.Para o terceiro contêiner, precisamos usar
display: inline-block;
e, em seguida, o conteúdo interno esticará esse contêiner e as barras de rolagem correspondentes aparecerão nos dois blocos pai.HTML
CSS
Você pode testá-lo aqui no Safari no iPhone.
Boa sorte!! 😉
fonte
isso parece divertido;)
Não vou discutir se é razoável.
Eu tentei com o RxJS:
Nós tampão cada 4º
touchemove
evento e, em seguida, fazer alguns cálculos altamente sofisticado, com as coordenadas dos quatro eventos (map(calculateDirection)
) que saídasRIGHT
,LEFT
,UP
ouDOWN
e com base em que tento rolagem vertical ou horicontal desativar. No meu telefone Android no Chrome, isso funciona;)Criei um pequeno playground , que pode ser aprimorado, reescrito, qualquer que seja ...
Cheers Chris
fonte