I know a lot of people will be angry about this being asked but...
I have a game using WebGL and the Pointer Lock API. Due to the nature of a lot of games having 'crouch' on CTRL I was wondering if there was any possible way to stop browser shortcuts like CTRL + S and CTRL + W...
At the moment I'm having to harshly disallow controls to have any CTRL key in them. I have set 'crouch' to C which is also common but I also have ideas about making a MMORPG-style game where you would have several action bars of abilities and a lot of combinations wouldn't be possible due to CTRL not being viable.
Note: In Chrome Ctrl+W is "reserved", use window.onbeforeunload
Note: Chrome requires event.returnValue to be set
In this code document.onkeydown is used for old browsers and window.onbeforeunload is used to Chrome and Firefox
Try this (disable Ctrl+W and Ctrl+S):
window.onbeforeunload = function (e) {
// Cancel the event
e.preventDefault();
// Chrome requires returnValue to be set
e.returnValue = 'Really want to quit the game?';
};
//Prevent Ctrl+S (and Ctrl+W for old browsers and Edge)
document.onkeydown = function (e) {
e = e || window.event;//Get event
if (!e.ctrlKey) return;
var code = e.which || e.keyCode;//Get key code
switch (code) {
case 83://Block Ctrl+S
case 87://Block Ctrl+W -- Not work in Chrome and new Firefox
e.preventDefault();
e.stopPropagation();
break;
}
};
Related
How can I get platform specific shortcut, or key binding for a specific process?
As an example how can I get the information that on Windows shortcut for copying is Ctrl + C ? (I'd like the information on all of the tagged languages if possible) I mean both text editing and file manager usage, and also would like to know if they're independent.
If I understand you, you want rewrite system command of browser. In browser all process start after some event. You can copy text , if you use command for copy: document.execCommand('copy'); and you can rewrite all events except paste.
Example:
document.addEventListener('keydown', (ev) => {
if(ev.keyCode === 67 && ev.ctrlKey === true) { // ctrl+c
console.log(ev);
ev.preventDefault();//block default action of browser
}
});
and trigger copy:
document.addEventListener('keydown', (ev) => { //ctrl+z
if(ev.keyCode === 90 && ev.ctrlKey === true) {
console.log(ev);
document.execCommand('copy');
ev.preventDefault();
}
});
All execCommand: https://developer.mozilla.org/en-US/docs/Web/API/Document/execCommand
To expand on my comment above, you need to check for evt.metaKey to catch standard macOS shortcuts, which use the same letter keys for the basic Cut/Copy/Paste/Undo as Windows (X/C/V/Z), but combined with the different command (⌘) modifier key.
It doesn't hurt in most cases if a Mac user can also use their control key as well as the command key for a shortcut, so the easiest solution is to check for both. Here's code from the previous answer modified to do that:
document.addEventListener('keydown', (ev) => {
if (ev.keyCode === 67 && (ev.ctrlKey || ev.metaKey)) { // Copy shortcut
console.log(ev);
ev.preventDefault(); // block default action of browser
}
});
On a Windows system, you'll probably never see a keyboard event with metaKey being true, because as far as I can tell, any keypress using the Win key (⊞), which theoretically maps to metaKey, will be intercepted by Windows before a web browser has any chance to look at it.
If you want to explore more about key events and modifier keys, I threw together a quick CodePen here for that: https://codepen.io/kshetline/pen/MWmKrPM?editors=1010
I have a Flex app running on a web page, and I want to use the Command+← key combination to trigger certain actions in the app. This is fine on most browsers, but on Safari, the browser intercepts this keyboard event and causes the browser "back" event instead. Is there a way, either through Flex or via JavaScript elsewhere on the page, that I can tell Safari not to do that?
Short answer, it's a (little) known bug on non-mac versions of safari. You can't reliably block all shortcut keys. Perhaps if you were more specific about what other shortcuts you're trying to block? Maybe some of them will work. e.g. cut paste copy have their own special methods of blocking. (Although it seems like you probably already know that.)
Are you using something like this?
function blockKeys(e) {
var blocked = new Array('c','x','v');
var keyCode = (e.keyCode) ? e.keyCode : e.which;
var isCtrl;
if(window.event)
isCtrl = e.ctrlKey
else
isCtrl = (window.Event) ? ((e.modifiers & Event.CTRL_MASK) == Event.CTRL_MASK) : false;
if(isCtrl) {
for(i = 0; i < blocked.length; i++) {
if(blocked[i] == String.fromCharCode(keyCode).toLowerCase()) {
return false;
}
}
}
return true;
}
You're not the first to get hit with this bug on here
Rather vague title, I know, but I'm binding a custom key event to the document object to catch AltR combination keypresses, like this:
document.body.onkeydown = function(event){
event = event || window.event;
var keycode = event.charCode || event.keyCode;
if (keycode === 82) {
if (event.altKey) {
if (!canReload) {
canReload = true;
window.location.href += "#doGreaseRefresh";
} else {
canReload = false;
window.location.href = window.location.href.replace("#doGreaseRefresh", "");
}
return false;
}
}
}
The code runs as expected but also produces a rather annoying "beep" sound as well. How can I prevent this? return false didn't prove to be the answer, so I'm wondering if it's even possible.
Oh, and if you're wondering, this is in a Chrome userscript (Content script) to refresh Stack Overflow's home page every 10 seconds if I've pressed AltR, and to stop refreshing once I've pressed AltR again. :)
Not being able to stop the beep is apparently a bug in Chrome: http://code.google.com/p/chromium/issues/detail?id=105500. return false works in Firefox without a beep.
Cheers-
As ZachB points out, this appears to be a bug with Chrome.
To work around this annoyance:
Go into the Windows control panel.
Select Sounds or System Sounds
Assign (None) for the sound of the Default Beep.
(I like to do this anyway, since it's 50 times more annoying than it is useful).
How does one capture a Mac's Cmd key via JavaScript?
EDIT: As of 2019, e.metaKey is supported on all major browsers as per the MDN.
Note that on Windows, although the ⊞ Windows key is considered to be the "meta" key, it is not going to be captured by browsers as such.
This is only for the command key on MacOS/keyboards.
Unlike Shift/Alt/Ctrl, the Cmd (“Apple”) key is not considered a modifier key—instead, you should listen on keydown/keyup and record when a key is pressed and then depressed based on event.keyCode.
Unfortunately, these key codes are browser-dependent:
Firefox: 224
Opera: 17
WebKit browsers (Safari/Chrome): 91 (Left Command) or 93 (Right Command)
You might be interested in reading the article JavaScript Madness: Keyboard Events, from which I learned that knowledge.
You can also look at the event.metaKey attribute on the event if you are working with keydown events. Worked wonderfully for me! You can try it here.
I found that you can detect the command key in the latest version of Safari (7.0: 9537.71) if it is pressed in conjunction with another key. For example, if you want to detect ⌘+x:, you can detect the x key AND check if event.metaKey is set to true. For example:
var key = event.keyCode || event.charCode || 0;
console.log(key, event.metaKey);
When pressing x on it's own, this will output 120, false. When pressing ⌘+x, it will output 120, true
This only seems to work in Safari - not Chrome
Basing on Ilya's data, I wrote a Vanilla JS library for supporting modifier keys on Mac: https://github.com/MichaelZelensky/jsLibraries/blob/master/macKeys.js
Just use it like this, e.g.:
document.onclick = function (event) {
if (event.shiftKey || macKeys.shiftKey) {
//do something interesting
}
}
Tested on Chrome, Safari, Firefox, Opera on Mac. Please check if it works for you.
For people using jQuery, there is an excellent plugin for handling key events:
jQuery hotkeys on GitHub
For capturing ⌘+S and Ctrl+S I'm using this:
$(window).bind('keydown.ctrl_s keydown.meta_s', function(event) {
event.preventDefault();
// Do something here
});
keyCode and which are now deprecated so it's advisable to avoid the answers that use those here.
One way to do this now is using the key property on the event argument that comes with DOM keyup and keypress events. Here's a simple example of how to do it:
document.onkeypress = (event) => {
if (event.key === 'Meta') {
console.log("Mac or Windows key was pressed!");
} else {
console.log("Another key was pressed")
}
}
This will trigger on the cmd key press on Mac (See Meta on the MDN docs). The only thing to note here is it will also trigger on the Windows key press too for the users keyboard/OS that support it.
If you need more granular understanding of which Meta key has been pressed, you can use the code property on event which can be either MetaLeft or MetaRight depending on which physical meta key ( cmd) was pressed.
Here is how I did it in AngularJS
app = angular.module('MM_Graph')
class Keyboard
constructor: ($injector)->
#.$injector = $injector
#.$window = #.$injector.get('$window') # get reference to $window and $rootScope objects
#.$rootScope = #.$injector.get('$rootScope')
on_Key_Down:($event)=>
#.$rootScope.$broadcast 'keydown', $event # broadcast a global keydown event
if $event.code is 'KeyS' and ($event.ctrlKey or $event.metaKey) # detect S key pressed and either OSX Command or Window's Control keys pressed
#.$rootScope.$broadcast '', $event # broadcast keyup_CtrS event
#$event.preventDefault() # this should be used by the event listeners to prevent default browser behaviour
setup_Hooks: ()=>
angular.element(#.$window).bind "keydown", #.on_Key_Down # hook keydown event in window (only called once per app load)
#
app.service 'keyboard', ($injector)=>
return new Keyboard($injector).setup_Hooks()
var element = //the DOM element to listen for the key on.
element.onkeyup = function(e) {
if(e.metaKey) {
//command key was pressed
}
}
if you use Vuejs, just make it by vue-shortkey plugin, everything will be simple
https://www.npmjs.com/package/vue-shortkey
v-shortkey="['meta', 'enter']"·
#shortkey="metaEnterTrigged"
As the default behavior of IE is to switch to the full screen mode on Alt-Enter command. I've to avoid this and have to attach a custom behavior.
Is it doable?
Not in JavaScript, no.
This is a behaviour of the application, which you don't really have control over (aside from browser extensions, and such).
You could try catching the key presses on your page, but it wouldn't prevent the user from easily circumventing it.
See http://www.webonweboff.com/tips/js/event_key_codes.aspx for a list of the character codes for keys. I'm pretty sure it's not reliable for catching combinations of key presses.
Besides, Alt+Enter in IE results in an expected behaviour and you should not try to override this via a webpage.
Since you can't beat 'em, join 'em. Meaning, since you can catch the event but can't stop it, how about you just run the same command in a timeout after the user presses alt+enter?
Example:
<script type="text/javascript">
document.onkeydown = handleHotKeys;
function handleHotKeys(e) {
var keynum = getKeyCode(e);
var e = e || window.event;
if (keynum==13 && e.altKey) { // handle enter+alt
setTimeout("toggleFullscreenMode",100);
}
}
function getKeyCode(e){
if (!e) { // IE
e=window.event;
return e.keyCode;
} else { // Netscape/Firefox/Opera
return e.which;
}
}
function toggleFullscreenMode() {
var obj = new ActiveXObject("Wscript.shell");
obj.SendKeys("{F11}");
}
</script>
DISCLAIMER: Tested in IE8. You will have to look at the browser and version to get this to work for the specific version of the browser you are targeting. This also assumes that the user will have javascript and activex objects enabled.