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);
Related
I have an application where elements inside of a SVG element can be drag and dropped (thanks to d3-drag and d3-zoom, see https://bl.ocks.org/mbostock/3127661b6f13f9316be745e77fdfb084 as an example for such a page) which can be also used on touch-enabled devices but what happens is that after a long press a context menu pops up (at least in IE11, Edge and Firefox) and is in the way, therefore I want to prevent the context menu from showing up in this case.
I could just disallow showing the context menu in general by handling the contextmenu event and doing .preventDefault() on the event object but I wonder whether a solution exists where the context menu is just blocked from showing in the touch case and it would still show up for e.g. right-clicks or when the menu key is pressed while the element has focus.
I thought at first I could look at the .button and .buttons properties of the event object but it seems like those values are arbitrarily 0 or 2 and it looks like it can be found in any combination when testing in various browsers on different systems.
The element already has touch-action: none.
Is there some working way to make the context menu just not show up a result of a touch long-presses?
It looks like .preventDefault() on the relevant touch events wouldn't be an option.
jQuery UI Touch Punch just solves it all.
It's a Touch Event Support for jQuery UI. Basically, it just wires touch event back to jQuery UI. Tested on iPad, iPhone, Android and other touch-enabled mobile devices. I used jQuery UI sortable and it works like a charm.
http://touchpunch.furf.com/
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.
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
In my Rails site, I have an element that I want to act as a link when clicked by a mouse (e.g. on a desktop), but not when touched on a touch-screen device (because there is also a hover behavior).
My understanding is that the JQuery .click event should not get triggered on a touch.
My coffeescript for setting the click handler is simply
...
$(this).click ->
location.href = url
...
(where "this" is the element in question)
I know this code works, because the click action works with the mouse. To ensure that it doesn't get triggered on a touch device, I use the device emulation in Chrome's Developer Tools to emulate a touch. However, when I do this, the method still fires and follows the link.
Is this a problem with the Chrome emulation or with my code? I want to know whether it will behave this way on real touch devices.
edit: Same thing happens with Firefox, so I'm thinking it's my code...
I realized that touch events trigger click events as well, later on in the event chain. To get the functionality I wanted, I kept the .click handler, but added a .touchstart handler where I called event.preventDefault() to short-circuit the rest of the event chain. This way, the .click handler fires for mouse clicks, but not for touches.
I understand the event mouseup for the window just isn't there for IE 7 and 8. I was wondering if anybody has found a work-around for this or if that is even possible.
I am currently working on a project where the user can click, drag to draw a line, and if the user drags outside of the window and lets up on the mouse, the drawing transaction will be cancelled.
Your difficulty sounds like it would be more from the window losing the scope of the event.
Are you using jQuery? With jQuery you can also tag onto the mousemove event and use the "which" attribute to detect if the button is pressed. This even fires when you come back into the window. But it DOES NOT fire when you are outside of the window.
Alternatively you can use $(window).mouseleave to detect when it leaves the window. However once it has left the window you cannot detect further mouse events (that would be a horrible flaw if they could detect when you right clicked on your desktop etc).
So you are somewhat limited by the browser security implementations in ALL browsers and won't be able to bypass that... but you can add some work around events to provide a "similar" experience.
Not directly, but I believe this should work.
In your mousemove event, check the Event.buttons property. If it is zero, then the user must have released the mouse outside the window and you can cancel the drag.
I am checking the browser compatibility of this now, so this answer may be edited. My computer's being slow right now!