jquery-archive / jquery-mobile

jQuery Mobile Framework
https://jquerymobile.com
Other
9.69k stars 2.41k forks source link

Swipe is buggy on Chrome/Android #5534

Open dzhongxu opened 11 years ago

dzhongxu commented 11 years ago

A panel should be closed when users swipe left or right. But this function does not work in Galaxy S1 and S3 for 1.3.0 beta.

Etherion commented 10 years ago

Swipe seems to be inconsistent even in the latest dev version for me (Chrome 31.0.1650.59 / Android 4.4.2 / Nexus 4). Tried it on http://jsbin.com/uzaret/951 and http://view.jquerymobile.com/master/demos/panel/ , the swipe gesture is detected no more than 30% to 50% of the attempts with relatively identical gestures. I can see also the same issue in the Dolphin browser. The panel demo swipe to close works fine on Firefox on Android and on Safari on my old iPhone 3GS, also works fine on the native browser (non-chrome) on my collegues' htc one on Android 4.3

zeusstl commented 10 years ago

I hate to say this, but this is too buggy to use in production and its one of the most crucial features of a mobile framework. On a Google Nexus 4 with Android 4.4.2 the results are at best the 30% - 50% mentioned above but only when my fat fingers are hitting it just right. Running some other experiments with extreme sensitivity values listed below seemed to improve the results so that I was able to get many successful swipes in a row when I was in the groove, but still averaged about 50% successful swipes overall.

    $(document).bind("mobileinit", function () {
        $.event.special.tap.tapholdThreshold = 10;
        $.event.special.swipe.horizontalDistanceThreshold = 3;
        $.event.special.swipe.verticalDistanceThreshold = 1000;
        $.event.special.swipe.durationThreshold = 4000;
        $.event.special.swipe.scrollSupressionThreshold = 1;
    });
mirko77 commented 10 years ago

It does not work at all on my Nexus 5 running 4.4.2. The panel only closes tapping on the part of the screen not covered by the panel.

gabrielschulhof commented 10 years ago

http://view.jquerymobile.com/master/demos/panel-swipe-open/#demo-page works perfectly on Android 2.3.5 native browser.

mirko77 commented 10 years ago

Just tested with Chrome 31.0.1650.59 on Android KitKat and it very buggy. 30% success rate

gabrielschulhof commented 10 years ago

I just tested with Android 4.1 and Chrome 31.0.1650.59 and it's also only about 60-70% reliable.

mirko77 commented 10 years ago

60/70% reliable on Android 4.2.2 Jelly Bean as well. Same Chrome build

rtucek commented 10 years ago

I've been testing on multiple mobile devices and browsers - all across different OS versions. Only Google Chrome ist very buggy as of ~33 % success rate on Android.

konceptdesignstudio commented 10 years ago

about 50% reliable with Chrome 33.0.1750.132 on Android 4.2.2 on a Samsung Tab 10.1. Has someone opened a bug report with Chrome on this as well?

Carlos487 commented 10 years ago

I'm also having that issue. I use jquery mobile inside a phonegap app and the scroll is inconsistent in Android 4.4 KitKat, the events swipeleft and right are not recognized most of time. I'm using a Moto X with 4.4.2 the behavior is correct in older OS version. Maybe is a bug with the new Chromium Webview,

arschmitz commented 10 years ago

Something is not consistent with the events that are fired in chrome vs the native browser is the problem. In kitkat chrome is that native browser. I am currently looking into what exactly is different to try and find a solution.

greaterking commented 10 years ago

Was working on HTC v4.3 ...updated today...an gloriously fails. Swipe events no longer trigger from document body.

rajukoltedev commented 10 years ago

jquery mobile panel features supported android version ?

steeren commented 10 years ago

From what I can see swipeleft and swiperight are unreliable on Android devices. We don't have many android test devices I can put my hands on. An old ZTE on Android 2, a Nexus 5 and a Nexus 4 (both running KitKat) all exhibit the exact same behaviour. Swipe events are not being triggered reliably (maybe 1 out of 10). We've found that swiping really really fast get more results but its totally unusable.

We've noted this issue since 1.4.0, and again on 1.4.2.

Heres a barebones example using the WIP JQM http://jsbin.com/ofuhaw/1262/edit

siamkreative commented 10 years ago

Tried http://jsbin.com/uzaret/891 on my Android 4.0.4 (i-mobile brand), native browser and it works 1 out of 10).

What is the most reliable alternative for swipe events?

diegotorres50 commented 10 years ago

Hello friends, coworkers and contributors for JQuery Mobile, I regret to say this, but We have the same problem related to swipe events, swipe is not working out fine for Samsung Galaxy S3, most of the attempts for doing swipe... swipe does not respond, sometimes is needed to do till 10 attempts to do swipe event responds.

A while a back, we've been developing a new WebApp project by using Jquery and Jquery Mobile, unfortunately we found out an erratic behavior that has to do with the coordinates when a displacement is done on axis "X" while a swipe event is given.

This behavior is gotten from built-in browser for Samsung Galaxy S3 (Android 4.3) but in especial when using Android 4.1.2 (Ice Cream Sandwich) on those devices.

As you are aware, the directive "horizontalDistanceThreshold​" has 30px as a value by default, and this is supposed is the minimum value expected during the horizontal displacement to be considered a swipe event, so far so good, said that, we were trying and getting the different values for debugging the swipe process on "$.event.special.swipe.handleSwipe" and we were able to detect several findings, among other things <> for axis "X" getting "start.coords[0]" and "stop.coords[0]" where "start" and "stop" are parameters used in "$.event.special.swipe.handleSwipe" function.

Why we say "wrong coordinates"? when you are using Samsung Galaxy S3, the window width is 360px, so, if you do a displacement breadthways on the screen, you should get at least more that 30px keeping in mind you dragged your finger through all your screen on axis "X", but this is not happening, the gotten average is 20px of displacement for axis "X" for all done proofs and this is given because of the range of coordinates on "X" between "start.coords[0]" and "stop.coords[0]" is low and not logic for a displacement so large.

By the time, we've decided to set "horizontalDistanceThreshold​" to 20px to get extreme sensitive and improve the results for Galaxy Samsung S3, however this is not a nice solution, in fact we think and we are concerned this change can be unstable for doing swipe on other devices.

Please, we need you to help us for getting a nice and stable solution.

We tested using:

. built-in browser for Samsung Galaxy S3 (Android 4.1) . jquery-2.1.0.min.js *. jquery.mobile-1.4.0.min.js

Besides we've read and we are aware of:

*. https://github.com/jquery/jquery-mobile/issues/5534 (Nothing seen here worked out for us) (even its links and attached documentation)

*. http://view.jquerymobile.com/master/demos/swipe-page/buenosaires.html (no worked out for us)

*. https://code.google.com/p/android/issues/detail?id=19827

*. https://github.com/jquery/jquery-mobile/issues/6805

*. http://jsbin.com/uzaret/891

*. https://api.jquerymobile.com/swipe/

*. http://demos.jquerymobile.com/1.3.0-beta.1/docs/api/events.html

*. http://blog.pkrss.com/?p=1284

Please, give us a hand, what needs to be done to fix this issue on Samsung Galaxy S3 (Android 4.1 and 4.3)

Skype: diego.torres.campuzano Twitter: diegotorres50 Gtalk: diegotorres50@gmail.com

Thanks so much for you attention.

Diego Torres Bogota Colombia

arschmitz commented 10 years ago

Sorry everyone about the delay in response to this. This has turned out to be a very complicated problem. The issue here is a change the team at google decided to make to how touchmoveevents are fired. Previously touchmove events were always fired while your finger was on the screen and moving. A change was made so that now on android or any version of chrome if you do not preventDefault() on the touchstart event or on the first touchmove event you will not continue to get touchmove events. However if you preventDefault on those events it will disable all scrolling.

This causes some very big problems for a swipe event. For example if you were to bind a swipe event to the body for navigation, and we were to make this work you would then no longer ever be able to scroll the page down or if you bind to a specific element any touch that start on that element will ever be able to start a scroll. This is not an acceptable result for us.

I have been working with the head of the team from google that implemented this change to attempt to find a solution. Chrome 35 beta gave great hope on this in fact swipe works 100% in chrome 35beta on android. In this version they made 2 important changes . First there is a "Slop" area around a touch which you can move within without triggering a scroll. In chrome 35 beta they have made it so movements in here will still trigger touchmove events for our purposes this worked perfectly and fixed the issue with swipe on android.

The second change is the addition of the touch-action css property. This allows you to specify the behavior of touch events on an element. This provides another possible fix for this issue by setting this prop to pan-y on the element which you bind swipe to it would allow vertical scrolling but not horizontal and would allow touch movements in the horizontal direction to still be triggered.

However with this good news there is also some bad news. After talking more with our contact at google the behavior that fixed the event ( emitting events in the slop area ) is being removed in the next build and will not make it into chrome 35 final. Apparently this behavior broke some popular sites and so it is being reverted in chrome.

So where does this leave us you may be asking?

I'm currently looking into one suggestion from google on this for making it work on current versions however it does not like this is going to work and even if it does its a significant change that would likely have to wait until 1.5. touch-action is promising here but will only be in new versions of chrome. It currently looks like we will not be able to support swipe on chrome or versions of android where this has been implemented.

We are working hard to find a solution to this issue and are open to suggestions but are limited by the behavior of the browser.

chetan-AD commented 10 years ago

I'm facing the same issue, I am testing my App on Nexus5 Android 4.4. The swipe is very hard on kitkat 4.4(2/10) on all other versions its working perfectly. I read all the comments above but haven't found any proper solution. Any upgrade on how's the bug going

bneigher commented 10 years ago

Anyone else notice a difference between the swipe performance on Webview vs Chromeview?

diegotorres50 commented 10 years ago

Thereafter We tried to use hammer.js to manage gestures, it seems to be a smart library by Jorik, however it is not a transversal solution given that some devices were showing random behaivors.

TNT-RoX commented 10 years ago

Here is the fix, the problem is two fold. The first is caused by different pixel densities and is solved: horizontalDistanceThreshold = window.devicePixelRatio >= 2 ? 15 : 30; verticalDistanceThreshold = window.devicePixelRatio >= 2 ? 15 : 30; The second fixes an issue with kitkat where a touchcancel is fired instead of a touchend. To identify if you are having this problem try tap->tap->swipe and it should fire the swipe event. This is resolved by attaching touchcancel to the touchend event.

diegotorres50 commented 10 years ago

Hi Andrew (TNT-RoX), We have found your feedback important, It seems a nice workaround to overcome this problem. We are going to test your first approach and looking forward to reach good results.

As for your second fix, sorry to bother you but it is not precise for us, Andrew, please, could you tell us what's wrong with kikat version related with swipe event? I think is very important to have clear what it is happening there.

Thanks again for your feedback and please keep in touch.

Greetings from Colombia

@diegotorres50

TNT-RoX commented 10 years ago

Hi Diego, greetings from South Africa.

The swipe gestures on kitkat fail for a completely different reason to other versions of android. On kitkat only if you do a swipe gesture the following sequence of events are fired.

  1. touchstart
  2. touchmove
  3. touchcancel (should be touchend)

Then if you tap once before a swipe the correct sequence of events are fired.

  1. touchstart
  2. touchmove
  3. touchend

So to overcome this kitkat bug I link the touchcancel to touchend for swipe events.

http://developer.android.com/guide/webapps/migrating.html#TouchCancel

@TNT-Rox

diegotorres50 commented 10 years ago

Andrew @TNT-RoX We only have a unique way to describe your first fix... 'EUREKA', thanks so much Andrew, you nailed it!

We are working for the most important newspaper and mass media in Colombia, and our tester team has tried on all mobile devices (tablets and cells) including Blackberry, Windows Mobile, Nokia, Android, Iphone and many other and I am excited to say... your first workaround has solved the first problem and in fact this is the quote (spanish is written here) from tester team to share you:

"Asunto: Re: BUG: JQueryMobile Swipe Event Does Not Work Out For Samsung Galaxy S3 With Android ICS 4.1

Buen Día,

Realizamos las pruebas en los dispositivos móviles y tabletas, la conclusión es que la experiencia es mucho más fluida. Respecto al s3 que era donde se presentaban más inconvenientes se mejoró la experiencia, de tal forma que durante las pruebas realizadas no se tuvo que hacer el gesto más de una vez para navegar en el contenido.

(...)

Cordialmente,

Diana ***** Analista de pruebas ISQTB - Certified Tester CHOUCAIR TESTING S.A. w.**cairtesting.*.



Bogotá - Colombia "

You are a genius, very smart of you to this fix...

On the other hand, we are going to review the second bug as for kit kat and We are going to keep you posted.

Are you on twitter? @diegotorres50 is my user.

See you around!

@diegotorres50

TNT-RoX commented 10 years ago

Diego @diegotorres50 it seems a cleaner scaling solution would be: horizontalDistanceThreshold = Math.round(30 / window.devicePixelRatio); Regards

diegotorres50 commented 10 years ago

Wow @TNT-Rox that adjustment looks nice and cleaner as you said, I am going to make extensive this to testing team and so to check again, however last fix exposed is working out nice, thanks.

Regarding kitKat bug, We tried on by using Nexus 4 with Android 4.4.2, but We did not find irregular behaivor, so, Andrew, how do you like if We send you an URL where our webApp is public so that you can test that behaivor? Did you ever wonder if this kitKat bug is a isolated case?

Please, let's get together by private message to review it.

Regards

@diegotorres50

arschmitz commented 10 years ago

@TNT-RoX I wish the fix were that simple. While you are correct we need to addtouchcancel, the rest of this does not fix the issue on kitkat at all. You can see where I made your changes in a branch http://view.jquerymobile.com/issue-5534/tests/functional/swipe.html. The issue is fully described here https://github.com/jquery/jquery-mobile/issues/5534#issuecomment-41387998 . We are working with the actual engineers from google on this, but so far the only solution is to wait for chrome 35 to go to stable, and once it does use touch-action.

arschmitz commented 10 years ago

@TNT-RoX as for the pixel density issue this is something we are looking into in more depth. Thank you for the PR on this.

diegotorres50 commented 10 years ago

Hi @arschmitz please, keep us posted if adjustments are going to be done related with pixel density issue, I just may say that proposal solution by @TNT-RoX is working out fine by the time, Our testing team has done several testes with several mobile devices and swipe gesture is perfect now.

arschmitz commented 10 years ago

@diegotorres50 The pixel density is only a potential issue about old android stock browser, this issue is about chrome, they are unrelated issues, however we are looking at both.

marcsyp commented 10 years ago

Can this problem be avoided by using the targetSDK preference in Phonegap?

Carlos487 commented 10 years ago

Not the problem persist even if you use the 19 SDK or and older one like 17.

mrextreme commented 9 years ago

After some testing I concluded that the main issue is swiping speed. I have to swipe REALLY fast to make it work. ( Different Samsung smartpones on Android, and latest stable Chrome. Firefox's sensitivity is perfect, the swipe works like a charm. )

arschmitz commented 9 years ago

@mrextreme please see https://github.com/jquery/jquery-mobile/issues/5534#issuecomment-41387998 above for the the real issue here and a full explanation.

TNT-RoX commented 9 years ago

@mrextreme @arschmitz is correct there is no direct fix for this issue.

arschmitz commented 9 years ago

@TNT-RoX thanks for confirming this for everyone. Its something I have put a LOT of time and effort into and have worked directly with a member of the chrome team on this. Its not an answer I like but its just how it is :( Thankfully at least starting in chrome 35 which is stable now its a simple fix for most cases with the touch-action css prop. Also once the jQuery pointer events polyfill https://github.com/jquery/jquery-pointer-events is ready we will be switching to using that in place of our vmouse abstraction. This will allow us to implement this in a consistent cross platform way. There is a test implementation of this in the polymer branch https://github.com/jquery/jquery-mobile/tree/polymer this currently however does not support ie8 or 9 as this uses the polymer pointer events polyfill directly rather then the jQuery version. Once the jQuery version is ready this will move to master.

TNT-RoX commented 9 years ago

My team of engineers and I have come up with a proof-of-concept shim that provides a workaround for this issue. https://github.com/TNT-RoX/android-swipe-shim

TNT-RoX commented 9 years ago

Shim is updated : https://github.com/TNT-RoX/android-swipe-shim

simonpapworth6742 commented 9 years ago

Chrome 36 has resolved this issue for me, anybody else?

arschmitz commented 9 years ago

@simonpapworth6742 yes they changed their thinking again on this. Talked with the head of web input at google a bit about this today and they are moving towards synchronous event processing in chrome for touch and scroll and have gone back on the idea of touch cancel. This fixes this problem in chrome.

RByers commented 9 years ago

Note that prior to Chrome 36 the recommended way to address this problem is to check the direction of movement on the first touchmove event and decide based on that whether to call preventDefault(). I.e. if the touchstart->touchmove distance is primarily horizontal than preventDefault the touchmove to continue to get events and trigger a swipe. If it's primarily vertical then don't call preventDefault and you'll get scrolling instead. Many sites follow this pattern, and it's sometimes necessary on browsers other than just Chrome (eg. in Safari if horizontal scrolling is possible, and now in IE mobile if you're using touch events instead of pointer events, possibly also in Firefox).

In Chrome 36+ as you've discovered you can use 'touch-action: pan-y' to make this simpler (although you still have to be careful to handle events only in the horizontal direction). You may also get away with handling the events without calling preventDefault or using touch-action, but it's probably not going to do exactly what you want in all cases. Eg. try swiping horizontally then changing directions and moving vertically - once you've started handling the swipe you probably don't want to allow vertical scrolling anymore, right?

arschmitz commented 9 years ago

@RByers we only support horizontal swipe. Scrolling during swipe in the vertical direction we really are ok with either way and would prefer to leave this up to the devs where possible since this is just a generic event like click. so if it should block scrolling or not would depend on the developers specific use case for the event. This is why the touchcancel event handling here was troublesome it forced us to pick scrolling vs swipe even when the desired effect had no need to block but may just be recording that the event occurred.

In general in apps made with jQuery mobile horizontal scrolling does not exist and would not be desirable this means that touch-action did fix this issue for the majority of situations. However the behavior in Chrome 36+ allows us to once again avoid making these decisions for the developers and just provide a generic event as we intended.

@RByers Thanks for sharing the background from the Chrome team!

RByers commented 9 years ago

Great, that's exactly why I pushed on this change - I'm glad it has worked for you!

Note that most browsers still require you to make some choice between scrolling and event handling - eg. even in Chrome 36+ if active scrolling actually occurs (i.e. it is scrollable horizontally) we'll start throttling the touchmove events to ensure scrolling remains smooth. In Safari once scrolling has started you won't receive the touch events at all. But the key thing here is that in both cases it depends on scrolling actually occurring - if the page doesn't scroll horizontally then you'll get a reliable event stream.

FWIW I just wrote a demo of the simple scenario (where relying on preventDefault is OK) here: https://plus.sandbox.google.com/u/3/+RickByers/posts/Ad5wGCceU2e

simonpapworth6742 commented 9 years ago

Hi Rick,

Thank you, Chrome 36 did arrive 24 hours later (I had no Idea that it was coming) and JQuery Mobile Swipe is working again, and luckily for me touch events are handled by JQM for me mostly.

Also thank you for your “RE: Web facing change PSA: touch scrolling will no longer send touchcancel in Chrome 35” email, I am today looking at Touch Cancel to see if JQM does correctly use it.

Again thank you

SImon

From: Rick Byers [mailto:notifications@github.com] Sent: 28 August 2014 01:09 To: jquery/jquery-mobile Cc: simonpapworth6742 Subject: Re: [jquery-mobile] Swipe is buggy on Chrome/Android (#5534)

Note that prior to Chrome 36 the recommended way to address this problem is to check the direction of movement on the first touchmove event and decide based on that whether to call preventDefault(). I.e. if the touchstart->touchmove distance is primarily horizontal than preventDefault the touchmove to continue to get events and trigger a swipe. If it's primarily vertical then don't call preventDefault and you'll get scrolling instead. Many sites follow this pattern, and it's sometimes necessary on browsers other than just Chrome (eg. in Safari if horizontal scrolling is possible, and now in IE mobile if you're using touch events instead of pointer events, possibly also in Firefox).

In Chrome 36+ as you've discovered you can use 'touch-action: pan-y' to make this simpler (although you still have to be careful to handle events only in the horizontal direction). You may also get away with handling the events without calling preventDefault or using touch-action, but it's probably not going to do exactly what you want in all cases. Eg. try swiping horizontally then changing directions and moving vertically - once you've started handling the swipe you probably don't want to allow vertical scrolling anymore, right?

— Reply to this email directly or view it on GitHub https://github.com/jquery/jquery-mobile/issues/5534#issuecomment-53658114 . https://github.com/notifications/beacon/4234429__eyJzY29wZSI6Ik5ld3NpZXM6QmVhY29uIiwiZXhwaXJlcyI6MTcyNDgwMzc0MCwiZGF0YSI6eyJpZCI6NjQ4MDA4Nn19--b544503ac3b7c92d9331c9a552cd6a0db4a8628b.gif

simonpapworth6742 commented 9 years ago

Thank you

From: Alexander Schmitz [mailto:notifications@github.com] Sent: 28 August 2014 01:34 To: jquery/jquery-mobile Cc: simonpapworth6742 Subject: Re: [jquery-mobile] Swipe is buggy on Chrome/Android (#5534)

@RByers https://github.com/RByers we only support horizontal swipe. Scrolling during swipe in the vertical direction we really are ok with either way and would prefer to leave this up to the devs where possible since this is just a generic event like click. so if it should block scrolling or not would depend on the developers specific use case for the event. This is why the touchcancel event handling here was troublesome it forced us to pick scrolling vs swipe even when the desired effect had no need to block but may just be recording that the event occurred.

In general in apps made with jQuery mobile horizontal scrolling does not exist and would not be desirable this means that touch-action did fix this issue for the majority of situations. However the behavior in Chrome 36+ allows us to once again avoid making these decisions for the developers and just provide a generic event as we intended.

@RByers https://github.com/RByers Thanks for sharing the background from the Chrome team!

— Reply to this email directly or view it on GitHub https://github.com/jquery/jquery-mobile/issues/5534#issuecomment-53659810 . https://github.com/notifications/beacon/4234429__eyJzY29wZSI6Ik5ld3NpZXM6QmVhY29uIiwiZXhwaXJlcyI6MTcyNDgwNTI0NiwiZGF0YSI6eyJpZCI6NjQ4MDA4Nn19--4f042b8e1ca8b2440b34792b73d2a44c8b8e2b7c.gif

dpa99c commented 9 years ago

It's nice that Chrome 36 fixed this, unfortunately there's a lot of old versions of Android out there with Webviews that contain this bug, so it still affects Cordova/Phonegap apps running on older devices. I used Hammer.js to detect the swipe gestures as a workaround.

mrextreme commented 9 years ago

or give Crosswalk a try

dpa99c commented 9 years ago

Crosswalk's great but has its cons too: ~20Mb additional size on the APK and the need to build a separate package for x86 and ARM

Carlos487 commented 9 years ago

@dpa99c but i've tried hammer.js when the issue was reported and it didn't work... There is a new version with this fix?

dpa99c commented 9 years ago

@Carlos487 I'm using v2.0.4 of hammer with Cordova 3.1.0 and JQM 1.4.5 Testing on Android 4.4.4 and iOS 8.3 and that seems to work fine