HammerJs: enable vertical scroll with horizontal swipe

会有一股神秘感。 提交于 2020-04-11 19:35:52

问题


I've got an angular 7 website, and I want to add horizontal swipe to one component, and vertical swipe to another (the components are in the same module). I'm using hammerjs for that.

By default, hammerjs disables vertical swipe, so I enabled swipping in all directions with the code below.

export class MyHammerConfig extends HammerGestureConfig
{
  overrides = <any>{
    swipe: {direction: Hammer.DIRECTION_ALL},
  };
}

//declare provider in AppModule
providers: [
    {
      provide: HAMMER_GESTURE_CONFIG,
      useClass: MyHammerConfig
    }
]

The problem is vertical scrolling does not work on the component with the horizontal swipe. From what I've read, the solution is to add touch-action: pan-y in the component with the horizontal swipe.

However, this works on chrome but safari does not recognise the touch-action property.

My idea was to declare multiple providers for HAMMER_GESTURE_CONFIG, at the component level:

  • on the component with horizontal swipe, use a provider which only allows horizontal swipe
  • on the other one, only enable vertical swipe

However, component-level providers do not seem to take my providers into account.

Here is some code I tried to use to only enable horizontal swipe

export class HorizontalHammerConfig extends HammerGestureConfig
{
  overrides = <any>{
    swipe: {Hammer.DIRECTION_HORIZONTAL},
    pinch: {enable: false},
    rotate: {enable: false}
  };
}

//Component declaration
@Component({
  ...

  providers:[
    {
      provide: HAMMER_GESTURE_CONFIG,
      useClass: HorizontalHammerConfig
    }],

Any idea?

Edit: Here is a stackblitz example demostrating the issue. The component level providers are ignored.


回答1:


I found the solution there.

Basically, the custom configuration has to override the buildHammer class, so different hammerjs options can be used depending on the context.

app.module.ts

export class MyHammerConfig extends HammerGestureConfig
{
  overrides = <any>{
    swipe: {direction: Hammer.DIRECTION_ALL},
  };

  buildHammer(element: HTMLElement)
  {
    let options = {};

    if (element.attributes['data-mc-options'])
    {
      try
      {
        options = JSON.parse(element.attributes['data-mc-options'].nodeValue);
      }
      catch (err)
      {
        console.error('An error occurred when attempting to parse Hammer.js options: ', err);
      }
    }

    const mc = new Hammer(element, options);


    // retain support for angular overrides object
    for (const eventName of Object.keys(this.overrides))
    {
      mc.get(eventName).set(this.overrides[eventName]);
    }

    return mc;
  }
}

And then, in the component template, pass the extra option as a json string.

component.html

<div (swipeleft)="onSwipeLeft()" data-mc-options='{ "touchAction": "pan-y" }'">
</div>

This works with safari/iOS



来源:https://stackoverflow.com/questions/60229437/hammerjs-enable-vertical-scroll-with-horizontal-swipe

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!