any_h
any_h

Reputation: 568

Hammer.js breaks vertical scroll when horizontal pan

I'm using Hammer.js to look for horizontal pan gestures, I've devised a simple function to clicks a button when panned left or right. It works okay, except the vertical scroll doesn't do anything on a touch device, or it's really glitchy and weird.

Here's the function:

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);
    });
};

I've tried to add a horizontal direction to the recognizer but it didn't really help (not sure if I did it even right):

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

Thanks!

Upvotes: 3

Views: 10926

Answers (5)

JithinAji
JithinAji

Reputation: 489

I was stuck on this for several days. Hope this will fix your problem.

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

When the relevant gesture is triggered, we applied a css class to the element, that would set the touch-action to none.

 mc.on('panmove panstart', event => {
        mc.addClass('is-dragging');
    }
);
.is-dragging {
        touch-action: none !important;
    }

Upvotes: 0

hypeJunction
hypeJunction

Reputation: 361

My problem was that vertical scroll was toggling a sidebar that was supposed to show/hide on horizontal pan/swipe. After looking at the event details, I realized that Hammer probably triggers panleft and panright event based on X delta and doesn't consider Y delta, so my quick solution was to check the pan direction in my handler:

this.$data.$hammer.on('panleft', (e) => {
    if (Math.abs(e.deltaY) > Math.abs(e.deltaX)) {
        return;
    }

    this.isVisible = true;
});

Upvotes: 0

fussinatto
fussinatto

Reputation: 7

Hammer 2.x does not support vertical swipe/pan. Documentation says:

Notes: When calling Hammer() to create a simple instance, the pan and swipe recognizers are configured to only detect horizontal gestures

You can however use older 1.1.x version, which supports vertical gestures

——

Clarification: this refers to a ‘simple instance’ which is when you don’t pass in any recognizer configuration as the second parameter. In other words these are the defaults but can (and usually should) be overridden.

Upvotes: -4

JohnP
JohnP

Reputation: 50019

User patforna is correct. You need to adjust the touch-action property. This will fix scrolling not working when you have hammer bound on a big element in mobile.

You create a Hammer instance like so

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

I was working on a pull to refresh feature, so I need the pan event.

Add the recognizers.

h.get( 'pan' ).set({
    direction   : Hammer.DIRECTION_VERTICAL,
});

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

Inside the eventhandler, you'd look at the event that was triggered and manually call on event.preventDefault() when you require it. This is applicable for hammer 2.0.6.

For anyone who's looking the pull to refresh code was taken from - https://github.com/apeatling/web-pull-to-refresh

Upvotes: 2

patforna
patforna

Reputation: 771

Try setting the touch-action property to auto.

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

From the hammer.js docs:

When you set the touchAction to auto it doesnt prevent any defaults, and Hammer would probably break. You have to call preventDefault manually to fix this. You should only use this if you know what you're doing.

Upvotes: 11

Related Questions