New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

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

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

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

This comment has been minimized.

Show comment
Hide comment
@taye

taye Dec 20, 2014

Owner

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).

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

This comment has been minimized.

Show comment
Hide comment
@nikolac

nikolac Dec 21, 2014

That worked, thank you!

nikolac commented Dec 21, 2014

That worked, thank you!

@nikolac nikolac closed this Dec 21, 2014

@tomber

This comment has been minimized.

Show comment
Hide comment
@tomber

tomber 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;

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

This comment has been minimized.

Show comment
Hide comment
@taye

taye Jan 12, 2015

Owner

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

This comment has been minimized.

Show comment
Hide comment
@tomber

tomber 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?

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

This comment has been minimized.

Show comment
Hide comment
@taye

taye Jan 12, 2015

Owner

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.

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

This comment has been minimized.

Show comment
Hide comment
@taye

taye Jan 12, 2015

Owner

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

This comment has been minimized.

Show comment
Hide comment
@tomber

tomber 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 !

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 added a commit that referenced this issue Feb 21, 2015

Improve 'auto' preventDefault with manualStart
If manuanStart is `true`, default prevention will happen only while
interacting.

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