Hammer.js在水平拖动时破坏了垂直滚动。

3
我将使用Hammer.js来寻找水平滑动手势,我已经设计了一个简单的函数,用于在向左或向右滑动时点击按钮。它运行良好,但在触摸设备上垂直滚动无法正常工作,或者出现故障和奇怪的问题。
以下是该函数代码:
var panelSliderPan = function() {
    // Pan options
    myOptions = {
        // possible option
    };

    var myElement = document.querySelector('.scroll__inner'),
        mc = new Hammer.Manager(myElement);
    mc.add(new Hammer.Pan(myOptions));

    // Pan control
    var panIt = function(e) {
        // I'm checking the direction here, my common sense says it shouldn't
        // affect the vertical gestures, but it blocks them somehow
        // 2 means it's left pan
        if (e.direction === 2) {
            $('.controls__btn--next').click();
        // 4 == right
        } else if (e.direction === 4) {
            $('.controls__btn--prev').click();
        }
    };

    // Call it
    mc.on("panstart", function(e) {
        panIt(e);
    });
};

我曾试图为识别器添加水平方向,但并没有真正起到帮助的作用(不确定是否正确):

mc = new Hammer.Manager(myElement, {
    recognizers: [
        [Hammer.Pan,{ direction: Hammer.DIRECTION_HORIZONTAL }],
    ]
});

谢谢!


请提供一个可工作的 jsfiddle,以便我们能够帮助您。 - Benjamin Mesing
5个回答

11

尝试将 touch-action 属性 设置为 auto

mc = new Hammer.Manager(myElement, {
    touchAction: 'auto',
    recognizers: [
        [Hammer.Pan,{ direction: Hammer.DIRECTION_HORIZONTAL }],
    ]
});

从 hammer.js 文档中得知:

当你把 touchAction 设置为 auto 时,它不会阻止任何默认事件,而且 Hammer 可能会出现问题。你需要手动调用 preventDefault 来解决这个问题。只有在你知道自己在做什么的情况下才应该使用此选项。


这应该是被接受的答案。调用preventDefault(或返回false)以防止事件的默认行为似乎非常标准(如果这是您想要的)。 - ChrisFox
3
可以让它重新可以滚动,但会破坏滑动手势。 - Jason G
1
很多 Hammer.js 的文档 几乎 让人感觉有点明白,但是你知道他们这句话真正的意思吗?我有一种直觉感觉我理解了这个评论,但同时也确实不太确定! - Simon_Weaver

2

用户patforna是正确的。您需要调整touch-action属性。这将修复在移动设备上将hammer绑定到大元素时无法滚动的问题。

您可以像下面这样创建一个Hammer实例:

var h = new Hammer(options.contentEl, {
    touchAction : 'auto'
});

我正在开发一个下拉刷新功能,所以我需要使用“pan”事件。
添加手势识别器。
h.get( 'pan' ).set({
    direction   : Hammer.DIRECTION_VERTICAL,
});

h.on('panstart pandown panup panend', eventHandler);

在事件处理程序中,您需要查看触发的事件,并在需要时手动调用event.preventDefault()。这适用于hammer 2.0.6。
对于任何正在查找下拉刷新代码的人,可以从https://github.com/apeatling/web-pull-to-refresh中获取。

0

我在这个问题上卡了好几天。希望这能解决你的问题。

 mc = new Hammer(myElement, {
            inputClass: Hammer.SUPPORT_POINTER_EVENTS ? Hammer.PointerEventInput : Hammer.TouchInput,
            touchAction: 'auto',
        });

当相关手势被触发时,我们会将一个CSS类应用于该元素,从而将touch-action设置为none。
 mc.on('panmove panstart', event => {
        mc.addClass('is-dragging');
    }
);

.is-dragging {
        touch-action: none !important;
    }

0
我的问题是垂直滚动会切换侧边栏,而侧边栏应该在水平拖动/滑动时显示/隐藏。查看事件细节后,我意识到Hammer可能会根据X delta触发panleft和panright事件,并不考虑Y delta,所以我的快速解决方案是在我的处理程序中检查pan方向:
this.$data.$hammer.on('panleft', (e) => {
    if (Math.abs(e.deltaY) > Math.abs(e.deltaX)) {
        return;
    }

    this.isVisible = true;
});

-4

Hammer 2.x不支持垂直滑动/平移。文档中提到:

注: 当调用Hammer()创建一个简单的实例时,平移和滑动识别器被配置为仅检测水平手势

但是您可以使用旧版本1.1.x, 它支持垂直手势。

——

澄清:这是指“简单实例”,即您不将任何识别器配置作为第二个参数传递的情况。换句话说,这些是默认值,但可以(并且通常应该)被覆盖。

我不是在寻找垂直滚动,而是水平滚动,这个可以工作。但它也禁用了正常的垂直滚动。 - any_h
你在这个问题上有进展了吗?我也遇到了类似的问题。 - Stradosphere
2
这不是真的,我相信。只需要在初始化“pan”识别器时将direction设置为Hammer.DIRECTION_VERTICAL即可。 - JohnP
像 @stradosphere 所说,Hammer 2 支持垂直平移,只需在构造函数中使用 DIRECTION_VERTICAL 常量即可。 - chesscov77
@Juan - 我没有在任何地方使用构造函数,只是使用了angular指令来绑定swipe事件,使用了hmTouchEvents模块和hm-swiperight和hm-swipeleft指令。 - Stradosphere
@stradosphere 看看这个代码片段:http://codepen.io/jtangelder/pen/ABFnd 看起来你正在使用一个 Angular 的包装器,这可能会引入其他问题。但是原生的 Hammer 完美支持垂直滑动。 - chesscov77

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接