I'm building an app in phonegap. The app makes heavy use of javascript and has a content area that should be scrollable. However I also need to use the touchStart and touchEnd events.
The problem is that, unless you use e.preventDefault on touchMove/touchStart, you will get the touchStart event only once and never again after that (Not useful).
If you do e.preventDefault() on either of those two, native scrolling is disabled (on mobile devices).
How do I allow native scrolling while also listening to touchstart + touchend?
Failing that, could I simulate native scrolling (using touchmove?)? I've tried my hand at this myself, and the result of that was frankly terrible.
Related
In past mobile apps that I developed, I found that the click event did not work as expected in all devices (for example: in games in which the user had to tap/click quickly on the screen, instead of triggering the click event, the double click was triggered), and using touchstart gave better results for what I wanted.
Since then, I started listening to the touchstart event instead of click; but testing on Chrome, I got the following warning message in the JS console:
Performing operations that require explicit user interaction on touchstart events is deprecated and will be removed in M54, around October 2016. See https://www.chromestatus.com/features/5649871251963904 for more details.
I visited the linked page (and the links inside it) and it seems that this new behavior is to avoid certain unwanted actions, and in particular to avoid third-party iframes or ads (my app has none) from opening pop-ups. I tried changing the event to touchend (as one of the links stated "The touchend event will continue to behave as before"), but got a similar warning message.
And my questions:
Is this something that only affects Chrome, or will it affect my web apps (with Cordova/Phonegap) for Android and iOS?
What event should I use to replace touchstart and avoid the issues I faced in the past? I could go back to click, but fast clicking/tapping would still be a problem.
When creating Cordova app, you target different OS versions, Android 5 and up has auto updating webview based on Chromium, so that problem will probably affect your apps.
But since Chrome 32, when using this viewport <meta name="viewport" content="width=device-width">, the click delay should go away (see this article), so you could safely use click event. Latest webviews on android 5 and 6 are based on Chromium 52.
You can also use fastclick library that will "fix" the click delay only where it's necessary
I'm developping a complex Single-Page-Application using ReactJS.
This page was initially a desktop browser application with lots of "onclick" listeners everywhere, including internal code, but also external plugins/libs that we can't modify easily.
But now we made it responsive, and it is available in both a mobile website and a Cordova/Phonegap app.
Just making the CSS responsive produces a nice result, without introducing touchstart event at all.
When the user touch an element with a click listener, the listener is called and the click event bubbles correctly (except on iOS but it can be solved)
So, unless I'm trying to implement touch specific complex features like drag&drop with touch, or special "synthetic events" like press, pinch, tap, swipe, (often provided by mobile-specific libraries), why would I need to use touchstart in any way?
For example I often see people trying to mix both click and touchstart in applications according to the device capabilities.
But if click works, why would I need to care about touchstart?
What are the advantages of touchstart that are not handled by click already?
Note: this is NOT at all about the 300ms click delay which can be solved in other ways.
The only reason we use touchstart/touchmove are for drag events, such as scrolling/inner-scolling detection.
For example, we want to detect the end of a scroll for infinite scroll.
On desktop we can use:
$('.whatever').scroll({ blahhhh
but on mobile we use:
$('.whatever').on('touchmove', blahhhh
Also you should definitely checkout How to bind 'touchstart' and 'click' events but not respond to both?
I have a bootstrap .btn that I want to toggle with the mouse click. The problem is that the response is way too slow on tablets, since the click arrives 300 ms after the touchstart in mobile browsers.
I tried binding the logic in the touchstart event, effectively breaking the app for desktop browsers where there is no touchstart. I then thought of binding the same logic also to click but then I get a repeated event in mobile browsers. I've juggling around, trying to unbind from click the first time I receive a touchstart, and so on, and managed to come up with a design so complicated that there is always some quirk here or there that I cannot solve.
For instance, I can't get a text input to receive focus in the tablet: if I do focus on touchstart then the click event returns the focus to the button. I tried jQuery Mobile's vmousedown, but I couldn't manage to have multi-touch (tapping more than one button at the same time only changed one of them). I don't want to reinvent a lot of wheels, and I'm sure I must be missing something obvious, either on jQuery Mobile, or plain JavaScript.
In concrete, I want an event like vmousedown that works both on desktops and mobiles, only fires once on each, and allows multi-touch.
Utilize Modernizr for handling actions based on the device, etc. It provides great cross-browser/platform support without the need to sniff User Agents and the like. Instead, it uses feature detection.
You can just use the Modernizr functions with jQuery's $(document).ready(function()});
$(function(){
if (Modernizr.touch){
// bind to touchstart, touchmove, etc and watch `event.streamId`
} else {
// bind to normal click, mousemove, etc
}
});
This code has been taken straight from the Modernizr Documentation
Also, here's another resource for performing touch tests
Late to the party, but note that jQueryMobile also has similar touch detection:
if ( $.mobile.support.touch ) {...
And no, IMHO, you are not missing anything obvious :), cross-platform / cross-device / touch-friendly features are still harder than they should be. For example, today I'm looking at a win8 surface tablet: touch-screen and a mouse. There are cases where i'd like to know which device was used. event.originalEvent.type should differentiate between tap and click, right? wrong :(.
I have a bootstrap .btn that I want to toggle with the mouse click. The problem is that the response is way too slow on tablets, since the click arrives 300 ms after the touchstart in mobile browsers.
I tried binding the logic in the touchstart event, effectively breaking the app for desktop browsers where there is no touchstart. I then thought of binding the same logic also to click but then I get a repeated event in mobile browsers. I've juggling around, trying to unbind from click the first time I receive a touchstart, and so on, and managed to come up with a design so complicated that there is always some quirk here or there that I cannot solve.
For instance, I can't get a text input to receive focus in the tablet: if I do focus on touchstart then the click event returns the focus to the button. I tried jQuery Mobile's vmousedown, but I couldn't manage to have multi-touch (tapping more than one button at the same time only changed one of them). I don't want to reinvent a lot of wheels, and I'm sure I must be missing something obvious, either on jQuery Mobile, or plain JavaScript.
In concrete, I want an event like vmousedown that works both on desktops and mobiles, only fires once on each, and allows multi-touch.
Utilize Modernizr for handling actions based on the device, etc. It provides great cross-browser/platform support without the need to sniff User Agents and the like. Instead, it uses feature detection.
You can just use the Modernizr functions with jQuery's $(document).ready(function()});
$(function(){
if (Modernizr.touch){
// bind to touchstart, touchmove, etc and watch `event.streamId`
} else {
// bind to normal click, mousemove, etc
}
});
This code has been taken straight from the Modernizr Documentation
Also, here's another resource for performing touch tests
Late to the party, but note that jQueryMobile also has similar touch detection:
if ( $.mobile.support.touch ) {...
And no, IMHO, you are not missing anything obvious :), cross-platform / cross-device / touch-friendly features are still harder than they should be. For example, today I'm looking at a win8 surface tablet: touch-screen and a mouse. There are cases where i'd like to know which device was used. event.originalEvent.type should differentiate between tap and click, right? wrong :(.
I'm trying to figure out how to add event listeners for windows touch events (like a big touch screen monitor, not mobile) in Windows 7 and can't seem to make things like touchstart touchend etc. trigger in any browser. Do these events just not fire in a browser like they do on an iPad?
As far as I know, those events are included only in some mobile navigators (not all, see http://www.quirksmode.org/mobile/tableTouch.html ). I don't think you can handle them on a standard browser like ff/ie/chrome. You'll have to use mousedown & cie.
Take a look at the v2 branch of hammer.js http://eightmedia.github.com/hammer.js/v2/, it's a nice touch event abstraction layer for iOS, Android, BlackBerry and also includes support for Windows touch events.