簡體   English   中英

HammerJS使用Mat-Tab滑動可阻止垂直滾動

[英]HammerJS swipe with Mat-Tabs blocking vertical scroll

因此,我在Angular應用程序中有一個組件,該組件具有用於數據類別的選項卡,以及用於選項卡內容的值數組。 我想使用HammerJS在選項卡之間滑動以獲得更原生的體驗。 我還安裝了這個虛擬滾動包: https : //github.com/rintoj/angular2-virtual-scroll以處理我為每個mat-tab下的列表准備的項目數量。 我將從此處顯示數據和標記開始:

這是在構建dummyData只是為了展示其結構:

  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);
  }

這是循環此數據以顯示選項卡和列表的標記:

  <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)方法:

  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類和導入:

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應用程序上一樣滑動屏幕並在選項卡之間移動。 此設置可以正常工作,並且實際上可以在選項卡之間滑動,然后加載新數據,並且還可以虛擬滾動數據以確保首先僅加載一定數量的項目。

我的問題是,由於Hammer設置了touch-action: none ,這現在阻止了移動設備上的所有垂直滾動touch-action: none virtual-scroll組件上沒有。 因此,我仍然可以使用鼠標滾動,但是任何垂直觸摸事件都不起任何作用。 我還注意到的一件事是(swipeup)(swipedown)不會在我的組件代碼中觸發任何事件。 我還刪除了swipeup和swipedown輸出,以確保它們不會妨礙滾動,但是在屏幕上垂直向上或向下拖動時仍然沒有阻礙。

我還可以確認使用virtual-scroll軟件包沒有問題,因為我已經嘗試過使用普通div進行嘗試,而該div並不是試圖延遲加載項目,而是一次加載所有項目。 仍然會遇到相同的問題,阻止任何垂直滾動方向。 由於我將使用virtual-scroll因為virtual-scroll比制表符的手勢更重要,因此我想在這里展示我的示例以及標記中的示例。

任何人都可以找到一種方法來在啟用水平滑動手勢時保留本地虛擬滾動嗎?

感謝您在此提供的所有幫助,在此先感謝您!

我想出了一種在保持垂直觸摸動作的同時進行此工作的方法。 我現在使用的Hammer配置看起來像這樣:

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)輸出,這是我編輯過的滑動方法:

  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樣式:

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

根據我的理解,這告訴系統在y方向滾動時允許本機觸摸操作,但是x方向將觸發panend事件,並且我可以從那里管理我的標簽索引。 我希望這對嘗試使用左右手勢同時保持垂直滾動行為的其他人有所幫助。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM