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.
Related
This one is pretty simple to recreate, just add a mousedown event listener to the document like
document.addEventListener('mousedown', () => console.log('mousedown'));
if you click anywhere within the viewport, you should see 'mousedown' logged as expected when the mouse is pressed down.
however, if you click exactly on the edge of the window, for example by setting the window to fullscreen and placing the cursor all the way to one side, you receive this log only when the mouse is released.
i have tried this in Chrome, Firefox and Safari and it works the same.
why is this happening? is there some other event that is delaying the regular firing of the mousedown event?
edit:
This is occurring on macOS Monterey 12.3
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
I am working on an RTS game where you can select units and right click to make them go somewhere. You can also shift right click to queue up a list of points you would like the units to travel to.
In all browsers except FF this is working perfectly.
In Firefox however the shift right click triggers a context menu (right click without shift does not). I am handling the contextmenu event and calling preventDefault but that doesn't seem to do anything in FF when the shift button is held.
Is there any way to block this behavior in FF?
My game is here: https://mod.it/4plhXo3l and the code in question in in the RTSBoard.js file on line 36.
I managed to get this working in Firefox by setting event.shiftKey to false, then calling preventDefault(), and stopPropagation(), then returning false. I then set the document model's onclick event and ondblclick events to the same function you wound up using for yourself, plus the added setting of the shiftkey to false. I also had to do this for mouseup events, because clicking and dragging was also causing context menus to pop up.
I'm not sure it can be fully 100% disabled, but this looks to be about the closest you can get it.
Answering my own question. It appears that calling preventDefault and stopPropagation in the document.onclick event solves the issue.
See this reddit thread for more discussion: http://www.reddit.com/r/javascript/comments/1agoj8/is_it_possible_to_block_the_shift_right_click/
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!
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/