How to detect 4 fingers touches on iOS without exit the app? - javascript

I am creating a web-app for iPad where I need to detect when 4 fingers touch my div.page.
I can easily do this with:
$('.page').on("touchstart", function(e) {
e.preventDefault();
touchesNbr = e.originalEvent.touches.length;
}
But my problem is that, even if there is a e.preventDefault(), iOS automatically show the "Which app would you like to kill" screen, when 4 fingers touch the screen and move slightly up.
Is there a way to avoid that?

Unfortunately, it seems impossible. Multitasking gestures are at the OS level, which means javascript can't access them.

Related

Knowing when to display on screen touch controls

I'm making a game that has 2 controls, left and right. On desktop those are the left and right cursor keys. On a machine without a keyboard or a machine primarily interacted with via touch screen I need to show buttons the user can press with their fingers.
Is there a way to detect when it's appropriate to display these touch buttons and when it's not?
solutions considered:
check for iPhone/iPad/Android
That covers most phones and tablet but of course it will be wrong on some other brands
use css media queries hover and pointer
AFAIK these won't help. A phone probably has hover: none and pointer: course but what about an iPad with a stylus. It should allow both hover:hover and pointer:fine making it indistinguishable from a desktop.
check by size
Seems flaky. Tablets have pretty large sizes. Often as large as laptops.
check for touch support
isTouchDevice = "ontouchstart" in window;
returns true on many Windows devices with touch screens

Pointer Events on mobile creates new pointerId on every pointerdown

To begin, I have read the documentation that says pointerId conveys no meaning
but to some extent it feels like it does.
When retrieving events from pointerdown on a desktop computer you can see that the pointerId property is always 1. I use this to verify if pointerdown event is coming from a mouse click.
However, when I open the Chrome developer tools and use the responsive mode and change it to a mobile device, let's say Pixel 2, and I click on the screen (which is simulated as a touch event) I get an incrementing pointerId on every click.
Now again, I understand it doesn't have a meaning but why does it stay 1 on desktop but go up infinitely on mobile?
I have inserted a simple snippet which when you run on the page it'll show 1 every click and if, you're on a desktop, click on full page and switch to responsive mode and pick a mobile device, it'll show an incrementing value.
window.addEventListener('pointerdown', (event) => {
console.log(event.pointerId);
});
Update
Thanks to the comments I realize that pointerId increments every time because there could be who knows how many fingers touching the screen of a mobile device so there is no way to differentiate them from others.
Why do I need (want) to keep track of pointerId?
Let's say I'm making an application that on desktop only needs the 1 mouse pointer but on mobile it requires 2 fingers to be used to interact with the application.
I need to keep track of where the left finger has been on the screen and what events it has caused and the same for the right finger. The problem comes where the incrementing pointerId comes in is there is no way for me to tell which finger is touching the screen.
Has anyone come across a solution for a problem like this?

How to capture touch pad input

I've looked everywhere for how to capture touch pad input for laptops but I can't seem to find anything for Chrome extensions/JavaScript.
Question: how can I capture the number of fingers down (not clicked, just down and potentially moving as you would with a mouse), their corresponding x,y coordinates, and their corresponding up events, for a touch pad on a laptop?
Clarifications:
I'm not interested in detecting touch screen events. Just touch pad
events.
Can assume the touch pad lives on 3 year old or newer lap tops.
I can't find it by now, but I somewhere read about this topic. But the synopsis is simple: it's a draft/in development but no browser supports it by now.
Here is the W3C draft: https://w3c.github.io/pointerevents/
I think it is not possible to do this using JavaScript only. Let's take it this way:
Consider the following situation:
I am using a Macbook pro 13in Retina Display, with multi touch and multi gesture touchpad.
Now Suppose if I have gesture settings in my Operating System that if I tap two fingers, register it as a normal Left Click, and when I tap a single finger, register it as a right click.
Now imagine we are capturing both the events, click and dblclick, now tell me which event will get fired when I will do a single tap with one finger. It will be a dblclick, and when I will do a tap with two fingers it will be click event fired.
Another Case: Imagine i have inverted scrolling turned on in my computer, now when I will scroll upwards my page will scroll downwards. And this is something which chrome/ firefox is not controlling.
Conclusion:
There can be varied number of such settings across varied types of operating system, across varied number of devices such as trackpads, trackballs, touchpads, mouse, magic mouse etc. This gives me a feel that there is a layer between the external hardware and the browser detecting the firing events and this layer is provided by the operating system. Its operating system which manipulate the events according to the user defined/preset settings.
There can be devices which intent to provide and fire multiple events like touch device, on touch they fire multiple events. But that is not the case with all the devices. So it doesn't matter if you are clicking from mouse or from the trackball or from the touchpad or from the touch screen you will get one common event that is a click, there is definitely a possibility that some more events are fired but they are dependent on the type of device and not on the settings you have done in your Operating System.
One way you can capture is the event is by establishing some sort of connectivity between your browser web page and operating system as suggested by #AlvaroSanz.
to develop such kind of extension, you need to write chrome native client with Windows Touch Input to make it happen.
I know that you´re asking for a solution for Chrome extensions/JavaScript but I´ve been searching and getting nothing, so I finished with a possible solution combining VB and JavaScript.
There is VB api for Synaptics (https://autohotkey.com/board/topic/65849-controlling-synaptics-touchpad-using-com-api/) and you can call javascript from VB (http://www.codeproject.com/Articles/35373/VB-NET-C-and-JavaScript-communication#cjfv), it's a long way, but it's a way.

Detect touch monitor with mouse attached

I wonder if it's possible to detect a kind of the device that runs a JS app.
What do I mean? - I want to serve touch monitors (that can be used as a normal touch devices and also can have a mouse attached - so they can behave as a normal PC) and classic touch devices (e.g. mobile phones - without possibility to use a mouse).
Is it possible? I know how to detect touch devices:
var isTouch = !!("ontouchstart" in window || navigator.msMaxTouchPoints);
But how to detect that there is a touch monitor or at least it has a mouse attached?
Well, you already have a bool reflecting touch capabilities. Obtaining the same for the mouse is doable, although not exactly elegant. You could do something like this:
var hasMouse;
window.addEventListener('mousemove', function mouseCheck(e) {
window.removeEventListener('mousemove', mouseCheck);
hasMouse = true;
});
Combined with user-agent inspection, you could get a decent estimate of the users device. Naturally some mobile browsers allow one to spoof a non-mobile user agent for 'desktop' like viewing. I'm not too fond of the idea of coercing interface formats in a situation where you aren't certain of the devices capabilities. How about simply showing a modal at application start, and using the isTouch && hasMouse, along with user-agent information to indicate the 'recommended' layout?

Number of touchmove events severely reduced on Android 2.3.3

I am currently working on the redesign of a website following the responsive design + mobile first approach.
I am trying to detect swipe events using JS on touch-enabled devices. For this purpose, I am using the following code:
document.addEventListener ('touchstart', function(event) {
//Get initial finger coords
}, false);
document.addEventListener ('touchmove', function(event) {
//Update final finger coords
}, false);
document.addEventListener ('touchend', function(event) {
//Compare initial and final coords, trigger swipe events if necessary
}, false);
I have tested this code on an iPad 1, an iPhone 4 and several devices running Android 2.2.1, and the result when I drag my finger on the screen is what I am expecting: the touchmove event fires several times (it can easily rise up to a hundred when doing a long gesture).
The problem comes when I test it on an Android 2.3.3 device (I'm using a Samsung Galaxy S2). Using its native broswer, the amount of touchmove events is reduced to only 1 (or rarely 2).
Am I doing something wrong or is it supposed to behave like that? Has anybody found the same problem? I was unable to find documentation about the behaviour of touchmove events in this version of Andriod.
You can test it here (using a touch-enabled device): http://jsfiddle.net/xs5BG/embedded/result/
It seems that galaxy S2 doesn't fire the touchmove after the scrolling starts to work. If you do a preventDefault it fires the events as expected.
Testing your jsFiddle example with my HTC Desire Z (running 2.3.3) i get many more than just one touchmove event - as desired. So i am unable to reproduce your actual problem with this device, although on the same API Level :( Interestingly enough your code also shows the problem that i am experiencing on my current project: The first touchmove event seems to have some kind of a threshold:
Putting the finger down and only moving a tiny bit will give 0 touchmove events... once over the threshold it will trigger touchmove events in intervals of milliseconds as it then recognises each and every pixel distance of a move (like it should do). Maybe this could be related to your phenomenon, respectively do you see this on your 2.3.3 device as well?
On many android versions if you don't preventDefault on touchstart the Android device will go into default scrolling mode and stops sending touch events to webview. So you would need to
document.addEventListener ('touchstart', function(event) {
event.preventDefault();
}, false);
Now all the touch events will fire, but default scrolling will be disabled.
There is a shim to overcome this issue that emulates a swipe gesture https://github.com/TNT-RoX/android-swipe-shim

Categories

Resources