HammerJs:启用水平滑动的垂直滚动
HammerJs: enable vertical scroll with horizontal swipe
我有一个 angular 7 网站,我想向一个组件添加水平滑动,向另一个组件添加垂直滑动(这些组件在同一模块中)。我正在为此使用 hammerjs。
默认情况下,hammerjs 禁用垂直滑动,所以我使用下面的代码启用了在所有方向上的滑动。
export class MyHammerConfig extends HammerGestureConfig
{
overrides = <any>{
swipe: {direction: Hammer.DIRECTION_ALL},
};
}
//declare provider in AppModule
providers: [
{
provide: HAMMER_GESTURE_CONFIG,
useClass: MyHammerConfig
}
]
问题是垂直滚动在水平滑动的组件上不起作用。根据我的阅读,解决方案是通过水平滑动在组件中添加 touch-action: pan-y
。
但是,这适用于 chrome,但 Safari 无法识别 touch-action
属性。
我的想法是在组件级别为 HAMMER_GESTURE_CONFIG
声明多个提供程序:
- 在具有水平滑动的组件上,使用只允许水平滑动的提供程序
- 在另一个上,只启用垂直滑动
但是,组件级提供程序似乎没有考虑我的提供程序。
这是我尝试使用的一些代码,仅用于启用水平滑动
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
}],
有什么想法吗?
编辑:这是一个 stackblitz example 演示问题。组件级提供程序将被忽略。
我找到了解决方案 there。
基本上,自定义配置必须覆盖 buildHammer
class,因此可以根据上下文使用不同的 hammerjs 选项。
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;
}
}
然后,在组件模板中,将额外选项作为 json 字符串传递。
component.html
<div (swipeleft)="onSwipeLeft()" data-mc-options='{ "touchAction": "pan-y" }'">
</div>
这适用于 safari/iOS
我有一个 angular 7 网站,我想向一个组件添加水平滑动,向另一个组件添加垂直滑动(这些组件在同一模块中)。我正在为此使用 hammerjs。
默认情况下,hammerjs 禁用垂直滑动,所以我使用下面的代码启用了在所有方向上的滑动。
export class MyHammerConfig extends HammerGestureConfig
{
overrides = <any>{
swipe: {direction: Hammer.DIRECTION_ALL},
};
}
//declare provider in AppModule
providers: [
{
provide: HAMMER_GESTURE_CONFIG,
useClass: MyHammerConfig
}
]
问题是垂直滚动在水平滑动的组件上不起作用。根据我的阅读,解决方案是通过水平滑动在组件中添加 touch-action: pan-y
。
但是,这适用于 chrome,但 Safari 无法识别 touch-action
属性。
我的想法是在组件级别为 HAMMER_GESTURE_CONFIG
声明多个提供程序:
- 在具有水平滑动的组件上,使用只允许水平滑动的提供程序
- 在另一个上,只启用垂直滑动
但是,组件级提供程序似乎没有考虑我的提供程序。
这是我尝试使用的一些代码,仅用于启用水平滑动
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
}],
有什么想法吗?
编辑:这是一个 stackblitz example 演示问题。组件级提供程序将被忽略。
我找到了解决方案 there。
基本上,自定义配置必须覆盖 buildHammer
class,因此可以根据上下文使用不同的 hammerjs 选项。
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;
}
}
然后,在组件模板中,将额外选项作为 json 字符串传递。
component.html
<div (swipeleft)="onSwipeLeft()" data-mc-options='{ "touchAction": "pan-y" }'">
</div>
这适用于 safari/iOS