Hold event triggers click/touch event in iOS safari #138

Closed
nikolac opened this Issue Dec 19, 2014 · 8 comments

Projects

None yet

3 participants

@nikolac
nikolac commented Dec 19, 2014

I'm using the "hold to start drag" model on touch devices. When I drop an element, a touch/click event is triggered at the x y coord of the start of the hold. I've tried preventDefault() and stopPropagation() from the hold callback, but I can't seem to stop the click.

Any help or workaround would be greatly appreciated.

Thank you

@taye
Owner
taye commented Dec 20, 2014

Because the hold event is fired from a timeout after the initial touschstart, you can't prevent the default using the hold event. You would have to call preventDefault on the down or up event (maybe both).

@nikolac
nikolac commented Dec 21, 2014

That worked, thank you!

@nikolac nikolac closed this Dec 21, 2014
@tomber
tomber commented Jan 12, 2015

I'm having the same issue when using hold to start drag. To use preventDefault on the down event solves this problem but breaks scroll of the target div. Any ideas of how to work around this would be much appreciated. The scrolling div has overflow-y: scroll;and -webkit-overflow-scrolling: touch;

@taye
Owner
taye commented Jan 12, 2015

I think that calling preventDefault on the first move event after going down also prevents scrolling. So something like this might work for you:

interact(target)
  .draggable({ manualstart: true })
  .on('hold', function (event) {
    var interaction = event.interaction;

    if (!interaction.interacting()) {
      interaction.start({ name: 'drag' },
                        event.interactable,
                        event.currentTarget);
    }
  })
  .on('move', function (event) {
    if (event.interaction.interacting()) {
      event.preventDefault();
    }
  });;
@tomber
tomber commented Jan 12, 2015

This prevents scroll of the div while dragging which is great, thanks!. Unfortunately it doesn't solve the original problem of the initial click/touch event triggered on hold. Any ideas for workaround to improve this solution to prevent the initial click event?

@taye
Owner
taye commented Jan 12, 2015

You could use interact.js' tap events instead of native click events. Other than that, I don't think there's anything that can be done.

@taye
Owner
taye commented Jan 12, 2015

Actually, you could also add a click event listener with useCapture which calls preventDefault and stopImmediatePropagation.

interact(target).on('click', function (event) {
  event.prevetnDefault();
  event.stopImmediatePropagation();
}, /* useCapture */ true);
@tomber
tomber commented Jan 13, 2015

It was actually the context menu on tap hold that was causing my problem since drag was interrupted when the contextmenu event fired. Disabling the context menu solves the problem:

.on('contextmenu', function (event) {
    event.preventDefault();
})

It all works perfectly when combined with the suggested solution for scroll on drag:

.on('move', function (event) {
    if (event.interaction.interacting()) {
        event.preventDefault();
    }
})

Thank you @taye !

@taye taye added a commit that referenced this issue Feb 21, 2015
@taye Improve 'auto' preventDefault with manualStart
If manuanStart is `true`, default prevention will happen only while
interacting.

See #138
8df9cd6
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment