垂直滚动时不允许水平滚动(反之亦然)

Jos*_*nor 17 html javascript css ionic-framework angular

我有一个列表,overflow-x并且overflow-y设置为auto。此外,我已经设置了动量滚动,因此使用可以在移动设备中很好地进行触摸滚动webkit-overflow-scrolling: true

但是,问题在于,我无法弄清楚在垂直滚动时如何禁用水平滚动。这会导致非常糟糕的用户体验,因为向左上方或右上方滑动会导致表格沿对角线滚动。当用户垂直滚动时,我绝对不希望任何水平滚动,直到用户停止垂直滚动为止。

我尝试了以下方法:

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();
}
Run Code Online (Sandbox Code Playgroud)

HTML:

<div
    class="cu-dashboard-table__scroll"
    [class.cu-dashboard-table__scroll_disable-x]="isScrollingVertically"
    [class.cu-dashboard-table__scroll_disable-y]="isScrollingHorizontally"
>
Run Code Online (Sandbox Code Playgroud)

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;
  }
}
Run Code Online (Sandbox Code Playgroud)

但每次我一组overflow-xoverflow-yhidden当其被滚动,滚动将毛刺和跳回到顶部。我还注意到这webkit-overflow-scrolling: true是发生这种情况的原因,当我将其删除时,该行为似乎停止了,但是我绝对需要这样做才能在移动设备中进行动量滚动。

垂直滚动时如何禁用水平滚动?

fro*_*975 15

通常,在设计中需要在移动设备上进行多轴滚动是一种不好的做法,除非您正在显示大型数据表。话虽这么说,为什么要预防呢?如果用户想对角滚动,那对我来说似乎不是世界末日。默认情况下,某些浏览器(例如OSX上的Chrome)已经执行了您要描述的内容。

如果必须进行单轴滚动,则可能的解决方案可能是通过touchstarttouchmove事件自己跟踪滚动位置。如果将拖动阈值设置为低于浏览器的阈值,则可以在开始滚动之前进行CSS填充,从而避免出现毛刺。同样,即使它仍然出现故障,您也可以开始触摸并获得触摸的当前位置。从这些记录中,如果记录了div的开始滚动位置,则可以手动将div滚动到正确的位置以抵消它跳到顶部的麻烦。可能的算法如下所示:

// Touchstart handler
if (scrollState === ScrollState.Default) {
    // Record position and id of touch
    touchStart = touch.location
    touchStartId = touch.id.
    scrollState = ScrollState.Touching

    // If you have to manually scroll the div, first store its starting scroll position:
    containerTop = $('.myContainer').scrollTop();
    containerLeft = $('.myContainer').scrollLeft();
}

// Touchmove handler - If the user has dragged beyond a distance threshold,
// do the css classes swap.
if (touch.id === touchStartId && distance(touchStart, touch.location > threshold) {
    scrollState = ScrollState.Scrolling;
    swapCssClasses();

    // If you have to manually scroll the div to prevent jump:
    $('.myContainer').scrollTop(containerTop + (touch.location.y - touchStart.y));
    // Do the same for horizontal scroll.
}

// Then, listen for debounced scroll events, like you're already doing,
// to reset your state back to default.
Run Code Online (Sandbox Code Playgroud)

第二个想法:在滚动处理程序中,不要更改css类,而是直接为要锁定的轴设置div的滚动位置。IE,如果要水平滚动,请始终将scrollTop设置为其初始值。不确定,这也可能取消滚动。您必须尝试一下它是否有效。


cup*_*_of 5

尝试这个

HTML
<div
  class="cu-dashboard-table__scroll-vertical"
>
  <div
    class="cu-dashboard-table__scroll-horizontal"
  >
    <!-- Scroll content here -->
  </div>
</div>


CSS
&__scroll {
  &-horizontal {
    overflow-x: auto;
    width: 100%;
    -webkit-overflow-scrolling: touch;
  }

  &-vertical {
    overflow-y: auto;
    height: 100%;
    -webkit-overflow-scrolling: touch;
  }
}
Run Code Online (Sandbox Code Playgroud)

与其使用一个 div 进行滚动,为什么不使用两个呢?一个用于 X,一个用于 Y