首页 > 解决方案 > 如何在 IONIC 4 中双击触发事件

问题描述

我正在按照本教程双击帖子以在 Ionic 4 中创建事件。

https://medium.com/@JordanBenge/ionic-4-quickly-add-ux-through-the-use-of-double-taps-5f6e3216a289 ,

我已经按照教程安装了锤子 JS。将其导入 main.ts

import 'hammerjs'

我的应用程序模块看起来像这样,

import { AngularFireFunctionsModule, FunctionsRegionToken } from '@angular/fire/functions';
import { DoubleTapDirective } from './directives/double-tap.directive'

export class CustomHammerConfig extends HammerGestureConfig {
  overrides = {
    'press': {time: 500},  // default: 251 ms
    'pinch': {enable: false},
    'rotate': {enable: false},
  };
} 
@NgModule({
  declarations: [AppComponent, DoubleTapDirective],
  // declarations: [AppComponent, NewTaskModalPage],
  // entryComponents: [NewTaskModalPage],

  imports: [
    HttpModule,
    BrowserModule,

  providers: [
    Camera,
    { provide: RouteReuseStrategy, useClass: IonicRouteStrategy },
 {provide: HAMMER_GESTURE_CONFIG, useClass: CustomHammerConfig},
 ],
  bootstrap: [AppComponent]
})

export class AppModule {}

双击指令

import { Directive, EventEmitter, HostListener, Output } from '@angular/core';

@Directive({
  selector: '[doubleTapable]'
})
export class DoubleTapDirective {

  @Output() doubleTap = new EventEmitter();
  @Output() tripleTap = new EventEmitter();

  constructor() {}

  @HostListener('tap',  ['$event'])
  onTap(e) {
    if (e.tapCount === 2) this.doubleTap.emit(e);
    if (e.tapCount === 3) this.tripleTap.emit(e);
  }
}

现在,我尝试将本教程实施到我的应用程序中,用户在提要中双击帖子并可以添加到他们的收藏夹中。使用以下代码,但这不起作用,因为当我双击时,视图会立即进入 PostID 详细信息页面。它不会创建 doSomething() 事件。

Tab4.html

<div  (doubleTap)="doSomething()"  id ="post" *ngIf="posts" >
          <!-- [routerLink]="['/tabs/details-feed/', post.postID]"> -->
        <ion-card *ngFor ="let post of posts" [routerLink]="['/tabs/details-feed/', post.postID]">
        <div id ="profileImage" >
           <img id ="profileImageIn" [src]="post.profileImage">
          </div> 
          <div  id ="userName" ><h6>{{post.username}}</h6></div>
          <img [src]="post.image">
        <!-- <div class="card-title">{{post.title}}</div> -->
        </ion-card>
         </div>  

Tab4.ts

import { ToastController } from '@ionic/angular';

 constructor(
    private aff: AngularFireFunctions,
    public toastController: ToastController
    ) {
  async  doSomething() {
      const toast = await this.toastController.create({
        message: 'Added to favorites.',
        duration: 2000
      });
      toast.present();
    }

如何成功实现双击事件?

标签: angulartypescriptangular7ionic4

解决方案


So the issue is that you have the router configured on the element that is the child of your tappable - see routerLink below:

<ion-card *ngFor ="let post of posts" [routerLink]="['/tabs/details-feed/', post.postID]">

The way the mouse or touch events stack works (let's skip assumption that this might use pointer events) is that when user interacts with your component the low-level events will be firing first (touch/mousedown etc) and more complex events that derive out of combination of low-level events will fire last (click):

  • touchstart
  • touchmove
  • touchend / touchcancel
  • mouseover
  • mousemove
  • mousedown
  • mouseup
  • click

Now "tap" is not official event that browsers recognize (nor double tap). All such tap events are "recognized" by hammer.js library.

So in your case to be able to work with tap / double tap events you need to remove router link as it relies on way lower level event that will always fire even before hammer.js double tap recognizer kicks in.

Instead of routerlink you would need to implement logic that "awaits" for double tap to take place and if after first tap the pause is too long -> then you call router to direct user to the detail page.

See this generic example by hammer: https://codepen.io/jtangelder/pen/pBuIw

Hope this helps.


推荐阅读