Skip to content
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

draggable blocks click #58

Closed
jdewit opened this issue Aug 1, 2014 · 16 comments
Closed

draggable blocks click #58

jdewit opened this issue Aug 1, 2014 · 16 comments

Comments

@jdewit
Copy link
Contributor

jdewit commented Aug 1, 2014

A link inside a draggable element does not fire a click event when clicked.

checkout plunkr and click the link in the item.

Only seems to happen on touch devices. (ipad3 android).

@taye
Copy link
Owner

taye commented Aug 2, 2014

Here are some things you can do:

  1. Use the Interactable#ignoreFrom setting to prevent actions that start from anchor elements - interact('*').ignoreFrom('a')
  2. Use interact's "tap" event instead of click - interact('*').on('tap', function ...). I just niticed that tap events are fired even if the pointer is dragged. I'll fix that soon.
  3. Use Interactable#preventDefault to avoid preventing the click. This would also mean that the page can be scrolled by the user when dragging. I also noticed that this setting is broken 😦

And by the way, in your demo you loop through similar elements and make them Interactable individually. You could instead pass a selector string to interact and it would work very similarly.

// instead of
var items = document.getElementsByClassName('item');

for (var i=0; i<items.length; i++) {
  interact(items[i]).draggable(...);
  ...
}

// you can do
interact('.item').draggable(...);
...

@taye
Copy link
Owner

taye commented Aug 2, 2014

The issues with preventDefault and tap that I mentioned (as well as another issue with tap) were fixed in 99f2f7c, 6aacb39 and 99f2f7c.

@taye
Copy link
Owner

taye commented Sep 8, 2014

Did any of the suggestions above solve your problem?

@jdewit
Copy link
Contributor Author

jdewit commented Oct 25, 2014

Sorry for the delay. Yes, that fixed it!

@jdewit jdewit closed this as completed Oct 25, 2014
@jdewit
Copy link
Contributor Author

jdewit commented Oct 28, 2014

Turns out the fix worked for the Android tablet but not Ipad 3.

@jdewit jdewit reopened this Oct 28, 2014
@taye
Copy link
Owner

taye commented Oct 28, 2014

Which fix did you use?

@jdewit
Copy link
Contributor Author

jdewit commented Oct 28, 2014

The plunkr uses the master branch. I did clear the cache. Tried on safari & chrome.

@taye
Copy link
Owner

taye commented Oct 28, 2014

I meant that which of the things that I suggested did you try?

  1. Use the Interactable#ignoreFrom setting to prevent actions that start from anchor elements - interact(target).ignoreFrom('a')
  2. Use interact's "tap" event instead of click - interact(target).on('tap', function ...).
  3. Use Interactable#preventDefault to avoid preventing the click.

@markadrake
Copy link

Hi Taye, I have a project where I can't seem to get the click event to fire properly. I can't post the source code at the moment because it isn't clean and to the point - but ultimately I have an un-ordered list element with images inside. The images have interact draggable assigned to them. The images also need to respond to the click event. But on mobile devices, the click event is ignored. Not globally - but only for elements that are draggable.

So I attempted solution number 2, and replaced the click event with interact's tap event. However, now desktop is messed up. On the tap (or click) event I toggle an info window's visibility. I also register a one time document click event so that the info window will be toggled off if the user interacts with anything else on the page. Now, on desktop, this event seems to fire off immediately. It's as if the "tap" event triggers a "click" event directly after running, even though I have e.preventDefault() and e.stopPropagation(). It's the damnedest thing.

Any thoughts on what I might be fighting with?

Do you think attaching the draggable event to the <li> and leaving the click event on the <img> would straighten things out?

@taye
Copy link
Owner

taye commented Jul 16, 2015

Hello!

The images also need to respond to the click event. But on mobile devices, the click event is ignored.

Because the images are draggable, interact.js calls preventDefault on the touchstart and touchend events on the mobile device. Browsers fire MouseEvents by default after TouchEvents and these simulated events can be prevented (at least on Webkit/Blink; I don't think it works on Firefox) by calling preventDefault on the TouchEvents and that also prevents the simulated click event.

Now, on desktop, this event seems to fire off immediately. It's as if the "tap" event triggers a "click" event directly after running, even though I have e.preventDefault() and e.stopPropagation(). It's the damnedest thing.

Click events can't be prevented by calling preventDefault or stop[Immediate]Propagation on the preceding mousedown and mouseup events. The only thing you can do is to stop the click event's propagation early on as I explained here: #217

interact(target).on('click', function (event) {
  event.stopImmediatePropagation();
}, true /* useCapture */);

taye added a commit that referenced this issue Jun 25, 2017
If the browser supports the {add,remove}EventListener options object
parameter, CSS touch-action and user-select can be used instead to
prevent scrolling and text selection.

With this change, clicks from touch events are no longer prevented on
Browsers that support the options parameter:
https://developer.mozilla.org/en-US/docs/Web/API/EventTarget/addEventListener#Browser_compatibility

Close #512, #517
Related to #58
@seltix5
Copy link

seltix5 commented Aug 14, 2017

hi all,
i found this problem too and since the click event is not unified between desktop and touch i develop this solution, maybe this can help someone else :

interact('.navbar-nav').draggable(settings).on('tap', function (event) {
    // because draggable blocks click event on touch, do manual trigger
    var link = jQuery(event.target).closest('a');
    if (link.exists() && event.pointerType === 'touch') {
        jQuery(event.target).trigger('click');
    }
});

@crawld
Copy link

crawld commented Apr 25, 2018

thanks @seltix5 your solution helped me. i had to modify it slightly (closest() returns an array), but now anchors work in draggable components.

@shubh3695
Copy link

shubh3695 commented May 6, 2019

Is there any permanent solution to this issue? The "fix" mentioned above stopped working after upgrading to v1.4.0

@tryhardest
Copy link

+1 @shubh3695 how did you figure it?

@taye taye reopened this Jun 25, 2020
@shubh3695
Copy link

shubh3695 commented Jul 17, 2020

Given that this issue was mostly on iOS, @tryhardest I had to capture "tap" events and filtered, ios device [detected by navigator], and then "click" the Element manually. it was a work-around, not a solution. I am no longer a part of that organization, where I did this 😄 , so dont remember it entirely, but yes, this was figured out after a long time.

@taye
Copy link
Owner

taye commented Sep 22, 2020

I'm closing this issue in favour of #859.

@taye taye closed this as completed Sep 22, 2020
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

7 participants