How do I make onclick event skip to offclick? - javascript

I am making a virtual keyboard for a touchscreen computer. I am using angular, html, and css only. How do I make it so that when I touch a key, even if I am holding the key down, the click is forced to "lift the mouse up."
The reason I am asking this is because when touching 2 characters within 500ms-1000ms, it ends up not registering a click.
If you have any tips about improving touchscreen usability feel free to comment :)

Open this demo on a touch device to test: http://jsbin.com/nibohe/4/
To get a native app feel (touch / mouse) UX:
$keybKeyElement.on("touchstart mousedown", function( event ){
event.preventDefault();
// Capture the key
// Send character to textarea
// other stuff
});
If you use only the click event on a touchscreen you have to
wait user's ~300+ ms for the up movement
~400ms delay for the browser to make it a valid click event.
where touchstart end event.preventDefault will kill the click, mousedown or other events used on desktop (non/touch) machines.

You could try using onmouseup instead of onclick

Related

Touchscreen get browser click or mouse event type

We have an Elo touchscreen that has multi touch. This can be probably for most touch screens as well, but we are trying to capture the "event type" on the body when a user touches the screen so we can trigger a timeout event. Right now we are using jQuery just for ease.
$('body').on("click mouseover mousedown touchstart touchend mouseup", function(e){
console.log("trigger type" + e.type);
});
Is there a way with Javascript (or jQuery) to get the touch type without first defining the events we want to watch for?
Instead of having to define and watching, setting a case statement, etc for "click", "mousedown", etc.
Is there a way to just get the event type?
My assumption is probably not, but since it is a proprietary touchscreen manufacturer, knowing the type from the DOM would be helpful. We are using Chrome/Chromium for a web app interactive for this.

Javascript window sometimes not receiving keyup

I'm developing an HTML5 canvas game, and I listen for key down/up like this:
window.addEventListener('keyup', function(event) {
// handle
});
window.addEventListener('keydown', function(event) {
// handle
});
This works fine for me on my Macbook Pro on Safari, Chrome, and Firefox.
However, a lot of my users are reporting having "sticky keys" -- they'll press a key to start moving upwards and later release that key, but the 'keyup' event won't be received and they'll be stuck continuously moving upwards until they press and release the up key again to trigger another "keyup" event.
Does anyone have any idea why this might be happening?
Things I've done already:
Reset all keys if the window loses focus using an event listener on the window object for the "blur" event. If the user switches tabs momentarily or the window somehow loses focuses otherwise, all keys will receive a keyup event and all movement in the game will stop.
Disable right click on the canvas using oncontextmenu='return false;'. I found that right clicking and bringing up the context menu would cause this bug to happen. It's the only reliable way I've found to reproduce it -- I'm really lost as to why so many users are seeing this bug even with right clicking disabled.

How to simulate touch gestures in browser, preferably chrome?

The purpose of this question is to learn how to test JS event listeners for touch events on mobile devices.
While on Chrome, press F12 to toggle Developer Mode.
Then, on the top-left of the developer partial, you will see a small icon saying "Toggle Device Mode" (Ctrl/CMD + Shift + M)
Then, you can switch between devices at the top.
This will mimic touch gestures made by a real device.
If you go into Developer Tools (F12), enter responsive design mode (Ctrl + Shift + M) and select a touch-enabled device, you can change it so it triggers touch events when you interact with the page (rather than mouse events).
I would recommend Hammerjs's touch emulator. It gets you touch events like Chrome, but also multitouch events (pinch in particular). It's easy to install on your page while developing. I'm using it to test stuff written in Fulcro (React). Works perfectly.
Open up the devtools and on the topleft corner there's an icon with a screen behind a phone. Click it to enable phone mode. You will know you are in phone mode because the page will be smaller and a circle will appear where your cursor was. Clicking will simulate a touch event.
First make sure your devtools is simulating touch ( In chrome , enter responsive mode and choose a mobile device). After that, this is how it works:
There are 4 touch events: touchstart, touchmove, touchend,touchcancel. If you want to simulate touchmove (ie click and move while finger is down) then you add an event listener to either the window or an element, and every firing of that event will trigger the callback you assign. The callback will receive the event as a whole , and it's a good idea to start off by console.log()-ging the whole event and seeing what is useful to you inside it.
For example a touchmove event will have an array called touches which will contain objects called touch. If there are 2 fingers down there will be two items in the array, each with a pageX and pageY property which would give you the position of that finger(although one can't simulate more than one finger in devtools - so you'd have to just use the first item([0]).
window.addEventListener("touchmove", (event) => { do something with event);

Which touch event should e.preventDefault() be called in to cancel a "click" on a touch device?

To prevent a click from firing, you can call e.preventDefault() in a click event handler. This lets you bind an event to mousedown, see if something happens like the mouse moving a certain distance, and if so, prevent the click when the mouse button is released.
A click handler with e.preventDefault() does not seem to prevent a click on certain touch devices however. (I am testing on an iPad mini). I have also tried calling e.preventDefault() in the touchend handler, which seems to do nothing.
Calling e.preventDefault() in the touchstart blocks the page from scrolling, and is also useless because it is too early to tell if the click should be cancelled. Only touchmove can decide if a cancel needs to occur.
The issue is, when a user drags a draggable element which is also a link, it needs to cancel the "click" of the link on fingerup. This works just fine on a desktop by cancelling the click event.
Is there an equivalent event I can cancel that stops an "armed click" from going off once the user lifts their finger up?
iOS is known to not register the click event property. This is likely due to the fact that iOS waits a little longer to determine how a click should be interpreted as:
the start of a pinching/zooming gesture
two or multiple-finger panning
the start of scrolling
the start of double tapping
a simple tap event (which we are trying to capture)
the start of touch-and-hold
Therefore, you can listen to the tap event instead, included in jQuery Mobile.
The jQuery Mobile tap event triggers after a quick, complete touch
event that occurs on a single target object. It is the gesture
equivalent of a standard click event that is triggered on the release
state of the touch gesture.
The tap event is not native, because it relies on conditionally listening upon touchstart to determine if the start and stop targets are the same: if so, jQuery Mobiel determines that it is indeed a genuine tap event and fires the custom, non-native event tap. This logic can be seen in the original source file, at line 75 onwards of ./js/events/touch.js.
An example usage is as follow:
$(selector).on('tap', function(e){
e.preventDefault();
});

Javascript: tracking touch events without .preventDefault() call

I'd like to track fingers in whatever mobile browser, without canceling the default behavior (which would be page scroll).
So I'm doing the following:
document.addEventListener('touchmove', function (ev) {
// fingers position tracking ode
}, false);
Now, if I want to continuously track the touchmoves, I have to call ev.preventDefault() in that function, which also disables the scrolling of the page. If I don't invoke this, I'll only get one touchmove event fired after which I can move my finger however long I want, - no other touchmove events will follow (until I release my finger and start a new touch/move sequence again that is).
My question basically is: how do I continuously track the fingers on the screen (bound to browser 'window'), without interfering with default browser behavior. I want to believe it is possible somehow :)
Unfortunately, your best bet is to take over the scrolling your self. There is fortunately a plugin for that http://cubiq.org/dropbox/iscroll4/examples/simple/

Categories