Jump to content
Search Community

iOS 13 Safari/WKWebView - Draggable double-dispatching "click" events

chris_hengst 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

Hi there. I'm having problems with my Cordova/Vue app which uses a lot of Draggables. 

 

Clicks sometimes get dispatched twice. 

 

Everything worked just fine until iOS 13 arrived. They must have changed something on how clicks are handled. 

 

I'm using Vue's methods to execute functions on click. 

 

Exemplary, simple code example:

 

<div class="dragContent">
  <div class="listItem" @click="toggleSomethingTrueFalse()" >
	Toogle something
  </div>

  ...

</div>

 

The "dragContent" is a Draggable.

 

Under iOS 13 the "toggleSomethingTrueFalse()" function will sometimes (often, but not always) be executed twice, which, in this case, leads to no result as the BOOL will be switched to true and immediately be switched to false again. This is a very annoying behavior :( 

 

I've already digged through the Draggable code and saw that a click event is dispatched in the syntheticClick function. If I comment this out it works most of the time in iOS 13 (clicks are not executed twice) but sometimes clicks are not executed at all! Which also leads to the problem on <= iOS 12 if I comment out the syntheticClick function. No clicks are executed.

 

I've also tried to increase the delay to generous 150ms in:

 

TweenLite.delayedCall(.15, syntheticClick);

This brings improvement, but still: Sometimes clicks will be executed twice (then with a larger delay - probably of 150ms?)

 

I've also tried the  data-clickable="true" attribute, but I really need the child divs to be a trigger for the draggable.

 

My app is very much based on Draggables and not really usable under iOS 13. Do you have an idea of how to get things working again?

 

PS: If I disable the Draggable, everything works great, so I'm assuming it has to be a Draggable issue.

Also, browser compatibility is not so important for me. I'm only developing for iOS, so if you have iOS-specific tips which may break other browsers, that's alright for me!

 

Thank you!

 

Link to comment
Share on other sites

53 minutes ago, chris_hengst said:

Everything worked just fine until iOS 13 arrived. They must have changed something on how clicks are handled. 

 

I see Apple finally added support for Pointer Events. That would be my best guess.

https://developer.apple.com/documentation/safari_release_notes/safari_13_release_notes

 

Does the same behavior happen with other browsers on iOS? 

 

And does Draggable's click still work?

Draggable.create(el, {
  onClick() {
    console.log("click");
  }
});

 

I haven't downloaded iOS 13 yet, so I can't test this stuff out right now.

  • Like 3
Link to comment
Share on other sites

Sorry to hear about the trouble @chris_hengst. It's an absolute nightmare trying to deal with all the different browser behaviors that vary wildly among vendors, especially when it comes to touch/click. It sounds like maybe Apple threw yet another wrench into things with the update (though I haven't updated yet so I'm not sure what's going on). I'm curious if this version of Draggable works any better for you: 

https://s3-us-west-2.amazonaws.com/s.cdpn.io/16327/Draggable-latest-beta.js

 

?

Link to comment
Share on other sites

Thank you for your answers.

 

The:

 

Draggable.create(el, {
  onClick() {
    console.log("click");
  }
});

 

still works.

 

I've also tested this version https://s3-us-west-2.amazonaws.com/s.cdpn.io/16327/Draggable-latest-beta.js, same problems.

 

And I've tested it in different browsers on iOS. My app is using WKWebView but it is the same in Safari and Chrome for iOS.


I just saw something interesting when starting to add event listeners for click and pointerup events.

 

If the behavior is as expected (means, clicks are working fine) this will be logged:

 

[Log] pointerup event fired
[Log] PointerEvent {isTrusted: true, pointerId: 1930726456, width: 0, height: 0, pressure: 0, …} 
[Log] click event fired 
[Log] MouseEvent {isTrusted: false, screenX: 0, screenY: 0, clientX: 0, clientY: 0, …}

 

If the problem occurs and there are two clicks fired it is logged this:

 

[Log] pointerup event fired
[Log] PointerEvent {isTrusted: true, pointerId: 1930726463, width: 0, height: 0, pressure: 0, …} 
[Log] click event fired 
[Log] MouseEvent {isTrusted: true, screenX: 1286, screenY: 209, clientX: 1286, clientY: 209, …} 
[Log] click event fired 
[Log] MouseEvent {isTrusted: false, screenX: 0, screenY: 0, clientX: 0, clientY: 0, …} 

 

So it seems like Safari sometimes only triggers a pointerup event which then will fire the syntheticClick as expected.

 

But sometimes will also trigger a click event which will execute the function and then execute it twice because syntheticClick is called because of the pointerup event.

 

Do you have a quick fix for this?  I really need tu update my app ?

Link to comment
Share on other sites

So, as I said I needed a quick solution for this, I've changed all affected @click events to @touchend which of course brought some extra work with it (registering if the finger was moved to not execute functions when it is not intended because the user was dragging).

This is now working fine on all iOS versions but of course it is not optimal... Just wanted to let you know.

 

If you have updates on this issue, please let me know anyways!

 

Cheers, Chris ✌️

  • Like 1
Link to comment
Share on other sites

  • 3 weeks later...

I have had similar IOS 13 issues. We are using draggable to swipe between multiple slides in a post.

 

Preventing the screen from scrolling vertically when swiping horizontal is critical,  also allowing the page to scroll vertically when swiping up or down on the same slides is also critical.  IOS 13 broke the fix we were using to accomplish both ....

 

$('html, body').off('touchstart touchmove', function(e){ 
    e.preventDefault(); 
});

 

The new beta for draggable linked above....

DOES prevent the screen from scrolling vertical when swiping horizontally - perfectly.

DOES NOT consistently scroll the page vertically when swiping or scrolling up or down on the slides - very bad :)

 

We love Greensock and gsap and we hope this feedback helps you guys create a better fix faster!!

 

We have tried editing the small lock of code above, and even crazy stuff like changing the "overflow" and "height" of the "html" and/or "body", nothing is working well enough as of yet. 

 

EDIT -- The beta for draggable works perfectly on the new iPadOS. The IOS 13 issue of vertically swiping on the slides to actually scroll the page continues not to perform consistently - it seems on any IOS 13 browser. Hope this helps!

Link to comment
Share on other sites

@Santoriello @chris_hengst Any chance you could provide a reduced test case with just the most basic setup to demonstrate the issue? I've been poking around various demos on my iPhone with iOS 13.1.2 and things seem to be working great for me. I'm sure I'm missing something, so any help you could provide in terms of a simple demo, I'd sure appreciate it. 

 

Oh, and as for your old fix (that doesn't work in iOS 13), have you tried adding a "touchforcechange" event listener (and calling preventDefault() on the event)? 

Link to comment
Share on other sites

Just to add another voice to this one - I have a sliding form using draggable, and within that I have range sliders that are also using draggable, so basically nested draggables. Pre iOS 13, all good, post 13 the slider drags the page and slide at the same time ?

 

I'll have a look at the pointer events and see if I can hack my way out of it...

Link to comment
Share on other sites

Not tried the beta yet, I'm on 2.1.0 and 0.17.0 of Draggable. 

 

I'm actually struggling to debug properly as I can't get the simulator to connect to safari (happens on both device and simulator) but I've been able to record the events and certainly seeing a lot of pointer/touch events that probably shouldn't be in the same place.

 

It's blocking me quite severely at the moment so I'll get on a demo tomorrow, and try the beta now.

Link to comment
Share on other sites

@Martin Shuttleworth TM so onRelease fires twice on the same Draggable in quick succession? Does the onPress fire multiple times as well? It's odd because there's code in the onRelease that checks isPressed and if it's false, it skips the onRelease altogether, and if it's true, it immediately sets isPressed to false (and does the onRelease). So something sound very strange here. I'm eager to see the reduced test case. A codepen would be ideal. 

Link to comment
Share on other sites

Right then - 

See the Pen gOOMoMp by fr1n63 (@fr1n63) on CodePen

 

Video below shows it in the simulator, working on iOS 12, getting weird in iOS 13. The weirdness in the iOS 12 part seems to be codepen more than anything else. 

 

https://gofile.io/?c=onufJ1

 

As for the query about onPress, it fires 3 times, although it's a pointerdown followed by two touchstarts, and then with onRelease it is two pointerups - I don't understand the significance of the pointerId in all this but both onRelease events have the same value, which seems unlikely.

Screenshot 2019-10-16 at 14.51.08.png

Screenshot 2019-10-16 at 11.59.29.png

Link to comment
Share on other sites

Ok, I have a really dirty hack fix, but I don't know the full implications of it, just that it fixes my specific issue...

 

if (touchType && type !== touchType) { //some browsers actually support both, so must we.
  element.addEventListener(type, func, capture);
}

Comment that out and all behaves as expected, at least in iOS 12/13, and Chrome on a mac.

 

Debugging a little bit more, it seems to be adding a second "pointerdown" via that statement which is making things unhappy.

Link to comment
Share on other sites

  • 2 weeks later...
— Draggable Issues 
Sorry about the delay, but we were waiting for a fix to our problem from... more responses here and/or new info online, and/or new releases for IOS13 or iPadOS. Please see the link below, it is a video of our desktop screen, showing how the site would work. The video is 21mb, has no sound, and is about 30 seconds. It might take a second or two to load. https://santoriello.com/example_video_2.mov
 
As you can see, we have a series of posts that can be scrolled vertically, and a series of slides in each post that are draggable, horizontally. The entire slide is draggable, the image and the text. The site should EITHER scroll the page vertically or drag the slides horizontally, but never both at the same time. Both iOS13 (?) and iPadOS allow for both to happen at the same time, very bad :)
 
— Draggable Production with iOS 13.1.3
I think we have this solved for now (for now?), with your help. First, we had to determine the direction of the drag (

See the Pen zyxgh?editors=001 by GreenSock (@GreenSock) on CodePen

) and then keep looking for solutions, which I think we found (https://greensock.com/forums/topic/21450-draggable-in-iframe-on-mobile-is-buggy/?tab=comments#comment-101225). So, if the swipe is close to being horizontal, only then do we add this code…
     $("body")[0].addEventListener("touchforcechange", handleTouchMove, false); 
Which will then call this function…
     function handleTouchMove(e) {
          e.preventDefault(); 
     }
And then ‘onDragEnd’ we add this code…
     $("body")[0].removeEventListener("touchforcechange", handleTouchMove, false);
I have no idea if this a permanent fix, please advise :)
 
— Draggable Latest Beta with iOS 13.1.3
Dragging horizontally works, scrolling vertically does not work at all when swiping up or down on the draggable slides, users have to swipe up or down on the part of the page that is not a slide, that is not draggable… unusable. 
 
 
— Draggable Production with iPadOS 13.1.3
This is still not working. ‘touchforcechange’ seems to be completely ignored. Any advice?
 
— Draggable Latest Beta with iPadOS 13.1.3
My previous post above indicated that everything worked perfectly with the latest beta on the iPad, not sure if I screwed up the testing, but the latest beta seems to have the same behavior as the production version of Draggable, with ‘touchforcechange’ being ignored (?).
 
— Other Notes
Desktop works fine with production and latest beta of Draggable. FYI, we add these listeners once everything is loaded, Not sure if it is helping or hurting. 
 
     document.addEventListener('touchmove', function(e) {
          //
     }, { passive: false });
 
     document.addEventListener('touchstart', function(e) {
          //
     }, { passive: false });
 
Any help would be appreciated, thanks :)
 
tom
Link to comment
Share on other sites

Thanks for the reply,

 

I am happy to report that iOS13.2 and iPadOS13.2 both work perfectly with changes referenced above while running the PRODUCTION version of GSAP, TweenMax, ThrowProps, and  Draggable. I will test the latest beta versions and report back :)

  • Like 1
Link to comment
Share on other sites

I downloaded the latest beta from my dashboard and used the files from the minified folder.

 

— iOS 13.2 with Beta GSAP

I could not get iOS13.2 to work with the four beta files mentioned above. I tried removing the listeners mentioned above, on the document and body, together and separately. However, trying to scroll the page when swiping up or down on the draggable did nothing in all cases :(.

 

— iPadOS 13.2 with Beta GSAP

This works beautifully.

 

FYI - I would really like to use the beta version 3, or at least the production version 3 when it is ready so we keep up to date. Please tag me or reply when there is anything remotely relevant to this issue - thanks!

 

:)

Link to comment
Share on other sites

3 minutes ago, Santoriello said:

— iOS 13.2 with Beta GSAP

I could not get iOS13.2 to work with the four beta files mentioned above. I tried removing the listeners mentioned above, on the document and body, together and separately. However, trying to scroll the page when swiping up or down on the draggable did nothing in all cases :(.

Can you produce a reduced test case for us to check out for this issue?

 

3 minutes ago, Santoriello said:

FYI - I would really like to use the beta version 3, or at least the production version 3 when it is ready so we keep up to date. Please tag me or reply when there is anything remotely relevant to this issue - thanks!

We're hoping to release GSAP 3 within the few weeks. You can sign up for GreenSock emails at the bottom of every page. That way you can be sure not to miss it :) 

Link to comment
Share on other sites

Your time is appreciated...

 

I should have said this previously - I wish I could create a codepen, but all things considered, I'm not talented enough to do that in a reasonable amount of time with this current project. I can message you privately if that is preferred :) I'm convinced the latest GSAP beta should be working for us, but somehow we have broken something. As I continue to test the difference between the production version and the latest beta, we can report some differences that may help to identify the issue.

 

— Using the production version of GSAP, the function below is called on all devices when swiping vertically on a draggable element.

— However, using the beta version of all files, the function below is NOT called using iOS 13.2 when swiping vertically on a draggable element. Something is preventing the page from scrolling, right?

 

$(window).on('scroll', function(){

     // take measurements, load new content if necessary

});

 

We should also say again, we can determine the direction of the swipe and correct issues that way, but I'm just not sure how to do that :) 

 

Again... appreciated.

 

Link to comment
Share on other sites

Hm, did you try the 3.0.0 beta files? I'm concerned that perhaps there was a misunderstanding and you're trying the "beta" of 2.1.x. Did you download the zip from your dashboard and open the folder named "gsap-3-beta" and use files from there? I made some improvements recently and I'd like to make sure you're testing the correct files. Would you mind trying again? 

 

And yes, it's fine to private message me with a demo. The simpler the better :)

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