Jump to content
Search Community

Draggable onRelease firing to soon on mobile.

RedGlove test
Moderator Tag

Warning: Please note

This thread was started before GSAP 3 was released. Some information, especially the syntax, may be out of date for GSAP 3. Please see the GSAP 3 migration guide and release notes for more information about how to update the code to GSAP 3's syntax. 

Recommended Posts

Hello fellow greensockers,

 

I hope every one is well!

 

Draggable issue,

I have a div on which I set a 3sec timer on "mousedown" or "touchstart" to enable draggable functionality. On "mouseup" or

"touchend" I clear the timer which doesn't let it enable the draggable when the mouse is realeased before 3 secs.

If draggable is activated I drop my listeners and work with draggable's listeners.

The same logic applies to disable back the draggable in it's onPress and on Release events but this time for 4 secs.

Everything works on desktop chrome. On mobile though If i just tap and hold my draggable the onRelease event gets fired without

even untapping resulting in the draggable not being able to deactivate. If i tap and drag (so that is calculated as drag event)

then onRelease fires correctly at the time the element is actually released, unless if the draggable stays tapped which will disabled it (as expected).

The think is draggable doesn't disable from a single long tap without dragging on mobile, because without dragging the onRelease fires

at a wrong time.

I tried setting minimumMovement to 0 just to check if in that case all clicks are interpreted as drag - to force a drag before release (since it works after a drag) but still no luck. 

I also tried using onClick, but onRelease fires earlier on a single tap and when the element stays tapped for a long time no onClick is fired.  

This behaviour can be tested on chrome dev tools mobile simulator too.

 

As usual codepen demo linked!

 

Any help will be appreciated!

Thanks!

See the Pen pPVZgd by RedGlove (@RedGlove) on CodePen

Link to comment
Share on other sites

Does this count as mobile?

 

kCIJgaX.jpg

 

That's a Surface Studio, and like a lot of Windows based computers, has a touchscreen. A good way to make your app unusable is to assume that touch is only on phones and tablets, or that touch is mutually exclusive of a mouse.

 

IE and Edge do not have touch events, they have Pointer Events. And touch events are no longer recommended to use in Chrome as they have switched over to pointer events, which is what Draggable is using. Chrome will call "touchcancel" for touch events. Please see this tutorial on the proper way to handle touch. And here's a polyfill for other browsers. 

 

  • Like 1
Link to comment
Share on other sites

Thanks for the quick reply @OSUblake!

Very interesting read. Especially for device support! Will definitely consider adding pointer event

support once I get it to work!

 

The thing is though, the issue is not related with my event handlers.

I created a second version of my pen where I removed all listener handling I do myself,

and just created the draggable which means draggable is now responsible for

event handling on that element.

 

In this scenario the draggable is enabled by default. All I do, is start a setTimeout

at the onPress event of the draggable so that if 4 seconds passed it will disable.

Then with onRelease I clear the timeout so that the above requires a continuous 4sec tap to run. 

If I tap the draggable and keep pressing without any dragging, onRelease will fire regardless of whether I untapped or not (unwanted behaviour onRelease shouldn't fire at all).

If I drag the draggable, and keep holding onRelease will fire only after I actually release the draggable (this is expected).

 

Thanks!

 

forgot the link!! :-D 

See the Pen QvrJjv?editors=1010 by RedGlove (@RedGlove) on CodePen

   

Link to comment
Share on other sites

Another more simplified example without even timers. Just console logs. Tap and keep tapping on the draggable.

A release will be fired without releasing.

 

-Again desktop is fine, chrome on mobile (android) or the chrome simulator fires release without untapping.

 

See the Pen GmdwBN by RedGlove (@RedGlove) on CodePen

Link to comment
Share on other sites

I have an inactive draggable.

I tap/click on it for 3 seconds it should get enabled for dragging.

I tap/click on it for 4seconds when is enabled and gets disabled.

This is all that should happen.

 

But focus on example 2 which the only thing that does is to disable

the draggable if you pressed it for 4 seconds.

And again as I mentioned the part that doesnt work is the part of disabling the

draggable on mobile when there is no dragging involved in the gesture. Other cases work.

 

use case 1:

-Draggable is active

Basically tap on the draggable for 4sec, even 10, while is activated (which is the deafult state) on example 2

without dragging anywhere. This should disable it. But in fact because an onRelease event is fired without actually releasing

the draggable then the timeout gets cleared from the onRelease function defined which clears the timeout.

 

use case 2:

-Draggable is active

But if I drag and hold for 4 sec the draggable will get disabled which is great.

 

Why can't I get use case 1 to have the same behaviour as use case 2.

 

This is tested on my android not just the simulator.

Link to comment
Share on other sites

I don't know why I didn't make this connection earlier,  but the problem was revealing itself to me from the very start.

 

Cqvbija.jpg

 

 

The context menu! You won't notice it using the simulator, but on a real touchscreen, it keeps popping up after releasing it. I added a context menu listener, and sure enough, it's being called at the same time release is being called.

 

See the Pen mmLvZb?editors=0010 by osublake (@osublake) on CodePen

 

 

I just looked at the source code, and Draggable adds a context menu listener that calls .endDrag(), so that's why onRelease is being called. Definitely something that's needs to be fixed.

 

 

  • Like 1
Link to comment
Share on other sites

Yeah, when a context menu pops up, it seemed pretty logical to stop the drag (trust me, without that behavior things feel really weird).

 

Do you guys think that the default behavior for Draggable should be to specifically PREVENT context menus completely? I'm a little worried that's too invasive, but maybe with touch it's most intuitive. I'm willing to consider adding that behavior to the next release of Draggable. I just always worry about making too many assumptions about developer intent. We could make that the default and then have a allowContextMenu:true as an option. 

 

You can solve the problem in that demo by preventing the default on the contextmenu event, and stopping propagation: 

draggableDiv.addEventListener("contextmenu", function(e) {
    e.preventDefault();
    e.stopPropagation();
});

 

 

  • Like 2
Link to comment
Share on other sites

I can totally understand if a context menu pops up, like when you right click, but there isn't one in this case. And the context menu event fires very fast, leaving you very little time to make a move. 

 

From what I can tell, the only context menu you can get with Draggable on a mobile device is when you long press on an image. That may or not be the what the developer wants, but it's probably safe to assume that the developer does not want the drag to end when there is no visual context menu.

 

The allowContextMenu property could work, but the developer might also want different behavior for a context menu that is triggered by touch than one triggered by right-click or keyboard (shift+f10). Not sure what the best option here is.

Link to comment
Share on other sites

Really nice Jack! 

 

I updated the Draggable used at the very first example in my question to use the link you've posted and 

I am getting the functionality I was looking for on mobile phones too.

 

And of course the flexibility of having it as an option it's just why we love GSAP!

 

Greensock style support!! Go greensock!!

  • Like 1
Link to comment
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now
  • Recently Browsing   0 members

    • No registered users viewing this page.
×
×
  • Create New...