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

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

问题描述

因此,我在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进行此操作,该常规的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!

推荐答案

我想出了一种在保持垂直触摸动作的同时进行这项工作的方法.我现在使用的Hammer配置看起来像这样:

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)="swipe($event)"上使用(panend)输出,而不是(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.

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

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