问题
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