使用 Mat-Tabs 阻止垂直滚动的 HammerJS 滑动 [英] HammerJS swipe with Mat-Tabs blocking vertical scroll

查看:21
本文介绍了使用 Mat-Tabs 阻止垂直滚动的 HammerJS 滑动的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

因此,我的 Angular 应用程序中有一个组件,该组件具有用于数据类别的选项卡,以及用于选项卡内容的值数组.我想使用 HammerJS 在选项卡之间滑动以获得更原生的体验.我也安装了这个虚拟滚动包:https://github.com/rintoj/angular2-virtual-scroll 来处理我为每个 mat-tab 下的列表准备的项目数量.我将首先在此处显示数据和标记:

SO I have a component in my Angular application that has tabs for categories of data with an array of values for the content of the tab. I want to use HammerJS to swipe between the tabs for a more native experience. I have installed this virtual scroll package also: https://github.com/rintoj/angular2-virtual-scroll to handle the amount of items I am preparing for the lists under each mat-tab. I'll start by showing the data and the markup here:

这里构建 dummyData 只是为了展示它的结构:

Here is building the dummyData just to show how it is structured:

  dummyData: any[] = [];
  selectedTab: number;

  constructor() {
    this.selectedTab = 0;
    for (let i = 0; i < 3; i++) {
      const x = {
        key: i,
        value: []
      }
      for (let j = 0; j < 100; j++) {
        x.value.push(j);
      }
      this.dummyData.push(x);
    }
    console.log(this.dummyData);
  }

这是循环此数据以显示选项卡和列表的标记:

and here is the markup that loops this data to show the tabs and the lists:

  <mat-tab-group dynamicHeight="true" mat-stretch-tabs [selectedIndex]="selectedTab">
    <mat-tab *ngFor="let cat of dummyData" [label]="cat.key">
      <ng-template matTabContent>
        <virtual-scroll [items]="cat.value" (update)="viewPortItems = $event" (swipeleft)="swipe($event)" (swiperight)="swipe($event)" (swipeup)="swipe($event)" (swipedown)="swipe($event)">
          <p *ngFor="let item of viewPortItems; let i = index;">{{ item }}</p>
        </virtual-scroll>
      </ng-template>
    </mat-tab>
  </mat-tab-group>

这是为 virtual-scroll 组件上的 (swipedirection) 输出触发的 swipe($event) 方法:

Here is the swipe($event) method that is triggered for the (swipedirection) outputs on the virtual-scroll component:

  swipe(event) {
    console.log(event);
    if (this.selectedTab === 0 && event.type === 'swiperight') { return; }
    if ((this.selectedTab + 1) === this.dummyData.length && event.type === 'swipeleft') { return; }
    switch (event.type) {
      case 'swipeleft':
        this.selectedTab += 1;
        break;
      case 'swiperight':
        this.selectedTab -= 1;
        break;
    }
  }

为了清楚起见,这里是我的 Hammer Configuration 类和导入:

For clarity here is my Hammer Configuration class and imports:

import * as Hammer from 'hammerjs';
import { HammerGestureConfig, HAMMER_GESTURE_CONFIG } from '@angular/platform-browser';

export class HammerConfig extends HammerGestureConfig {
  overrrides = <any>{
    'swipe': { velocity: 0.4, threshold: 20, direction: Hammer.DIRECTION_ALL },
    'pinch': { enable: false },
    'rotate': { enable: false }
  }
}

还提供了:{ provide: HAMMER_GESTURE_CONFIG, useClass: HammerConfig }

这样做的目的是让用户能够滑动屏幕并在标签之间移动,就像用户在 Android 或 iOS 应用程序上一样.此设置工作正常,实际上确实在选项卡之间滑动并接下来加载新数据,并且虚拟滚动数据以确保首先只加载一定数量的项目.

The purpose of this is for the user to be able to swipe the screen and move between tabs, like a user would on an Android or iOS application. This setup works correctly and does in fact swipe between the tabs and loads the new data next and also virtual scrolls the data to make sure that only a set amount of items load at first.

我的问题是,现在这会阻止移动设备的所有垂直滚动,因为 Hammer 在 virtual-scroll 组件上设置了 touch-action: none.所以我仍然可以用鼠标滚动,但任何垂直触摸事件都不起作用.我还注意到的一件事是 (swipeup)(swipedown) 不会在我的组件代码中触发任何事件.我还删除了 swipeup 和 swipedown 输出,只是为了确保它们不会阻碍滚动,但在屏幕上垂直向上或向下拖动时仍然没有.

My problem is that this now blocks all vertical scrolling from a mobile device as Hammer sets touch-action: none on the virtual-scroll component. So I can still scroll with a mouse, but any vertical touch events do not do anything. One thing I also noticed is that the (swipeup) and (swipedown) do not trigger any event in my component code. I have also remvoed the swipeup and swipedown outputs just to make sure they aren't hindering the scroll, but still nothing when vertically dragging up or down on the screen.

我也可以确认这在使用 virtual-scroll 包时没有问题,因为我已经用普通的 div 尝试过它并没有试图偷懒加载项目,但只需一次加载它们.仍然遇到阻止任何垂直滚动方向的相同问题.由于我将使用 virtual-scroll,因为它比选项卡的手势更重要,我想在这里展示我的示例,并在标记中使用它.

I also can confirm this doesn't have an issue with using the virtual-scroll package as I have tried it with a normal div that is not trying to lazy load the items, but just loads them all at once. Still get the same issue blocking any vertical scroll direction. Since I will be using the virtual-scroll as that is more important that the gestures for tabs, I want to show my example here with that in the markup.

有人想办法在启用水平滑动手势的同时保持原生虚拟滚动吗?

Anyone find a way to keep the native virtual scroll while enabling the horzontal swipe gestures?

我感谢这里的所有帮助,提前致谢!

I appreciate any and all help here, thanks in advance!

推荐答案

我想出了一种方法,可以在保留垂直触摸操作的同时使这项工作正常进行.我现在使用的锤子配置如下所示:

I figured out a way to make this work while retaining vertical touch actions. The hammer config I am using now looks like this:

export class HammerConfig extends HammerGestureConfig {
  overrrides = <any>{
    'swipe': { velocity: 0.4, threshold: 20, direction: Hammer.DIRECTION_ALL },
    'pinch': { enable: false },
    'rotate': { enable: false },
    'pan': { velocity: 0.4, threshold: 20, enable: true, direction: Hammer.DIRECTION_ALL }
  }
}

pan 设置为启用.

然后我在我的标记上使用 (panend) 输出:(panend)="swipe($event)",而不是 (swipedirection) 输出,这是我编辑的滑动方法:

Then I am using the (panend) output on my markup: (panend)="swipe($event)", instead of the (swipedirection) output and this is my editted swipe method:

  swipe(event) {
    console.log(event);
    event.preventDefault();
    if (this.selectedTab === 0 && event.additionalEvent === 'panright') { return; }
    if ((this.selectedTab + 1) === this.menu$.length && event.additionalEvent === 'panleft') { return; }
    switch (event.additionalEvent) {
      case 'panleft':
        this.selectedTab += 1;
        break;
      case 'panright':
        this.selectedTab -= 1;
        break;
    }
  }

从这里开始,这仍然会阻止任何垂直滚动,但是重新启用垂直滚动的一件事是在我的 virtual-scroll 上设置 touch-action: pan-y 样式代码>元素:

From here this still blocks any vertical scrolling, but the one thing that will reenable the vertical scrolling is setting the touch-action: pan-y style on my virtual-scroll element:

virtual-scroll {
    height: calc(100vh - 106px);
    padding: 0px 0px;
    will-change: transform;
    touch-action: pan-y !important;
}

根据我的理解,这是告诉系统在沿 y 方向滚动时允许本机触摸动作,但 x 方向将触发 panend 事件,我可以管理我的标签索引从那里.我希望这对尝试使用左右手势同时保留垂直滚动行为的其他人有所帮助.

From my understanding, this is telling the system to allow the native touch-action when scrolling in a y direction, but the x direction will then fire off the panend event and I can manage my tab index from there. I hope this can be of help to anyone else trying to use side-to-side gestures while retaining the vertical scrolling behavior.

这篇关于使用 Mat-Tabs 阻止垂直滚动的 HammerJS 滑动的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆