I was trying to implement the CTRL+S feature for a browser based application. I made a search and came across two scripts in the following to questions
Best cross-browser method to capture CTRL+S with JQuery?
Ctrl+S preventDefault in Chrome
However, when I tried to implement it, it worked but, I still get the default browser save dialog box/window.
My Code:For shortcut.js:
shortcut.add("Ctrl+S",function() {
alert("Hi there!");
},
{
'type':'keydown',
'propagate':false,
'target':document
});
jQuery hotkeys.js:
$(document).bind('keydown', 'ctrl+s', function(e) {
e.preventDefault();
alert('Ctrl+S');
return false;
});
I believe e.preventDefault(); should do the trick, but for some reason it doesn't work. Where am I going wrong.Sorry if it is simple, still learning jJvascript.
You don't need any of those libraries, just try this:
$(document).on('keydown', function(e){
if(e.ctrlKey && e.which === 83){ // Check for the Ctrl key being pressed, and if the key = [S] (83)
console.log('Ctrl+S!');
e.preventDefault();
return false;
}
});
The problem was that your code halted at the alert(), preventing your function from interrupting the save dialogue.
(Still uses jQuery)
This is to just add a different implementation to the question used by me.
Adapted from a SO answer.Also,works for MAC
document.addEventListener("keydown", function(e) {
if (e.keyCode == 83 && (navigator.platform.match("Mac") ? e.metaKey : e.ctrlKey)) {
e.preventDefault();
//your implementation or function calls
}
}, false);
People are still viewing this it seems, so it's probably worth pointing out that there is no need for jQuery on this one, here:
function keydown (event) {
var isCtrlKeyDown = navigator.platform.indexOf("Mac") > -1 ? event.metaKey : event.ctrlKey,
isSDown = (event.key && event.key === "s") || (event.keyCode || event.which) === 83 // falls back to keycode if no event.key
if (isCtrlKeyDown && isSDown) {
// prevent default event on newer browsers
if (event.preventDefault) {
event.preventDefault()
}
// ... your code here ...
// prevent default event on older browsers
return false
}
}
// register the event
if (document.addEventListener) {
document.addEventListener("keydown", keydown)
} else {
document.onkeydown = keydown
}
That should work in all browsers, this will also work for folks using alternative keyboard layouts from QWERTY on Windows, which reports incorrect key codes (at least on Chrome 56 on Windows 10 in my testing)
However, this looks kind of clunky, and confusing, so if you are only supporting modern browsers, you can do the following instead:
document.addEventListener("keydown", function keydown (event) {
if (navigator.platform === "MacIntel" ? event.metaKey : event.ctrlKey && event.key === "s") {
event.preventDefault()
// ... your code here ...
}
})
As of 2017, instead of using e.keyCode === 83 you should use e.key === 's' as the former is deprecated.
No need to use any plugin, just use below jquery code
$(document).bind('keydown', 'ctrl+s', function (e) {
if (e.ctrlKey && (e.which == 83)) {
e.preventDefault();
//Your method()
return false;
}
});
Since you are using alert, the execution halts at the alert and "return false" is not executed until you close the alertbox, thats the reason you see the default dialog.
If your method is long running better use asyn method method instead.
Related
Here I tried to disable the Ctrl+P but it doesn't get me alert and also it shows the print options
jQuery(document).bind("keyup keydown", function(e){
if(e.ctrlKey && e.keyCode == 80){
alert('fine');
return false;
}
});
http://jsfiddle.net/qaapD/10/
I am not sure how can I disable the Ctrl+P combination itself using jQuery or JavaScript.
Thanks
You can't prevent the user from printing, but you can hide everything when the user prints the document by using simple CSS:
<style type="text/css" media="print">
* { display: none; }
</style>
Updated fiddle.
If you would like to show the visitor a custom message when he/she try to print rather then just a blank page, it's possible with client side code but first wrap all your existing contents like this:
<div id="AllContent">
<!-- all content here -->
</div>
And add such a container with the custom message:
<div class="PrintMessage">You are not authorized to print this document</div>
Now get rid of the <style type="text/css" media="print"> block and the code would be:
if ('matchMedia' in window) {
// Chrome, Firefox, and IE 10 support mediaMatch listeners
window.matchMedia('print').addListener(function(media) {
if (media.matches) {
beforePrint();
} else {
// Fires immediately, so wait for the first mouse movement
$(document).one('mouseover', afterPrint);
}
});
} else {
// IE and Firefox fire before/after events
$(window).on('beforeprint', beforePrint);
$(window).on('afterprint', afterPrint);
}
function beforePrint() {
$("#AllContent").hide();
$(".PrintMessage").show();
}
function afterPrint() {
$(".PrintMessage").hide();
$("#AllContent").show();
}
Code is adopted from this excellent answer.
Updated fiddle. (showing message when printing)
After much testings on various browsers, it is easier to intercept the keys when they are down (not pressed) because some of this "App integrated keys" are difficult to intercept with the "keypress" event.
I came up with this script that is sort of cross browser compatible (I didn't test for Microsoft's IE). Notice that the browsers return different codes for some keys. In my case I wanted to prevent Ctrl+P.
The key "P" on chrome is seen as e.keyCode == 80, on opera, it is e.charCode == 16, while on firefox it is e.charCode == 112
$(document).on('keydown', function(e) {
if((e.ctrlKey || e.metaKey) && (e.key == "p" || e.charCode == 16 || e.charCode == 112 || e.keyCode == 80) ){
alert("Please use the Print PDF button below for a better rendering on the document");
e.cancelBubble = true;
e.preventDefault();
e.stopImmediatePropagation();
}
});
I used jQuery.
This is basically Peters answer from above. The difference is I added the accountability for mac when pressing the cmd+p button combo to print a page.
$(document).on('keydown', function(e) {
if((e.ctrlKey || e.metaKey) && (e.key == "p" || e.charCode == 16 || e.charCode == 112 || e.keyCode == 80) ){
alert("Please use the Print PDF button below for a better rendering on the document");
e.cancelBubble = true;
e.preventDefault();
e.stopImmediatePropagation();
}
});
To disable Ctrl+P printing by using javascript use below code:
window.addEventListener('keydown', function(event) {
if (event.keyCode === 80 && (event.ctrlKey || event.metaKey) && !event.altKey && (!event.shiftKey || window.chrome || window.opera)) {
event.preventDefault();
if (event.stopImmediatePropagation) {
event.stopImmediatePropagation();
} else {
event.stopPropagation();
}
return;
}
}, true);
Your code works in the jsfiddle example? What browser are you using? Itested it with the latest chrome and it worked fine.
You can also add:
e.preventDefault();
This Actually worked for me in chrome. I was pretty suprised.
jQuery(document).bind("keyup keydown", function(e){
if(e.ctrlKey && e.keyCode == 80){
Print(); e.preventDefault();
}
});
Where Print is a function I wrote that calls window.print(); It also works as a pure blocker if you disable Print();
As noted here: https://stackoverflow.com/a/20121038/2102085
window.print() will pause so you can add an onPrintFinish or onPrintBegin like this
function Print(){
onPrintBegin
window.print();
onPrintFinish();
}
(Again this is just chrome, but Peter has a downvoted solution below that claims the keycodes are different for ff and ie)
had a journy finding this, should be canceled on the keydown event
document.addEventListener('keydown',function(e){
e.preventDefault();
return false;
});
further simplified to :
document.onkeydown = function(e){
e.preventDefault();
}
given you have only one keydown event
there are some shortcuts you simply can't override with javascript, i learned it the hard way. I suppose CTRL+P is one of them.
one way to override them would be to deploy a chrome pacakged app.
Try this
//hide body on Ctrl + P
jQuery(document).bind("keyup keydown", function (e) {
if (e.ctrlKey && e.keyCode == 80) {
$("body").hide();
return false;
}
});
Here is the code, it work for me
document.addEventListener("keydown", function(event) {
if (event.ctrlKey && event.key === "p") {
event.preventDefault();
}
});
<script>
function isKeyPressed(event)
{
if(event.ctrlKey == 1)
{
alert("Please Submit exam form befor printing");
}
}
</script>
<body onkeydown="isKeyPressed(event)">
<p>this is the solution</p>
</body>
If you want to disable printing of your webpage you're wasting your time: it can't be done. Even if you work out how to capture CTRL-P users can still use the browsers menu bar to find the print command, or they can take a screen shot of the browser.
Stop trying to control the user, put your energy into making your site / app more useful, not less useful.
edit 2016: in the 3 years this has been up it has gathered 3 downvotes. I'm still not deleting it. I think it is important to tell fellow developers when they are given impossible tasks, or tasks that make no sense.
edit 2018: still think it's important that people that have this question read this answer.
In the snippet below, Ctrl+Enter (event.which == 13) is working. However, Ctrl+R (event.which == 9) is not.
if ($('.selector')) {
$(document).keypress(function(event) {
if ( event.altKey && event.which == 13 ) {
$('.link a').trigger('click');
} else if ( event.altKey && event.which == 82 ) {
$('.link a').trigger('click');
} else {
return false;
}
});
}
The problem with your code is the keyPress listener behaves differently and uses a different set of keyCode. For keyPress the r key is 114 while for keyDown it is 82.
Also another problem is browser's default reload function will override your function because keypress is executed after you release the key. To solve this, change keypress to keydown.
$(document).keydown(function(e){
if(e.which === 82 && e.ctrlKey){ //keycode is 82 for keydown
alert("Pressed!");
e.preventDefault(); //stop browser from reloading
}
});
http://jsfiddle.net/DerekL/3P9NS/show
PS: It seems like Firefox is ignoring e.preventDefault (which by W3C standards it should). The best thing to do to support all browsers is to choose another combination, or use ctrl + alt + r.
if(e.which === 82 && e.ctrlKey && e.altKey){
Based on some quick testing at http://api.jquery.com/event.which/, it seems you want event.which == 82, not event.which == 9. Although most browsers tend to use Ctrl + R to refresh the page, so this might not be the best way to handle whatever you're doing.
A cross-Browser solution to prevent Ctrl+R refresh page:
LIVE DEMO (works in Firefox, Chrome, Safari, Opera)
var keyEv = navigator.userAgent.indexOf('Firefox')>-1?["keypress",114]:["keydown",82];
$(document)[keyEv[0]](function(e) {
if ( e.ctrlKey && e.which == keyEv[1] ){
e.preventDefault();
alert("CTRL+R");
}
});
By simply testing for our navigator.userAgent you can decide what Key event listener to use and the respective R key code.
If you need to handle both R and ENTER in combination with Ctrl than you just need this little tweak:
LIVE DEMO (again all browsers :) )
var keyEv = navigator.userAgent.indexOf('Firefox')>-1?["keypress",114]:["keydown",82];
$(document)[keyEv[0]](function(e) {
var k = e.which;
if ( e.ctrlKey && k==keyEv[1] || k==13 ){ // no XBrowser issues with 13(Enter)
// so go for it!
e.preventDefault();
alert("Do something here");
}
});
For whatever reason I can't capture "SHIFT+TAB" combination.
I am using the latest jQuery.
Same result if I use other ajax/javascript, etc.
Here is a simple example that should work as I currently understand it...
event.which or event.KeyCode are always "undefined" only shiftKey exists in a scenario involving a "SHIFT+TAB" or backward keyboard traversal, traditionally inherent in windows based apps/web or otherwise...
function ShiftTab()
{
debugger;
if(event.KeyCode == 9 && event.shiftKey) // neither this line nor the following work
// if (event.which == 9 && event.shiftKey) // shift + tab, traverse backwards, using keyboard
{
return true;
}
else
{
return false;
}
}
this seems to be yet another item related to tab order that no longer works as it traditionally worked in Microsoft.Net WinForm/WebForm based apps.
If you are using jQuery, this should be how the code is working. Make sure keyCode is lower case. Also, jQuery normalizes keyCode into which:
$(document).keyup(function (e) {
if (e.which === 9 && e.shiftKey) {
ShiftTab();
}
});
If you're into terse JavaScript:
$(document).keyup(function (e) {
e.which === 9 && e.shiftKey && ShiftTab();
});
jQuery 1.7+ on syntax:
$(document).on('keyup', function (e) {
e.which === 9 && e.shiftKey && ShiftTab();
});
I created a function which I wired up to my button's onkeydown event. I used onkeydown, because onkeypress would not capture my tab key press
function ShiftTab(evt) {
var e = event || evt; // for trans-browser compatibility
var charCode = e.which || e.keyCode; // for trans-browser compatibility
if (charCode === 9) {
if (e.shiftKey) {
$('#controlName').focus();
return false;
} else {
return true;
}
}
I took this approach to deal with two specific problems:
onkeypress would not capture tab key press
When click shift-tab, shift key press would trigger function, so I had nest the shiftkey modifier check
use same code inside keypress event.
the tab changes the element between keypress and keyup.
here we get event.key = tab and event.shiftKey = true.
How to detect Ctrl+V, Ctrl+C using JavaScript?
I need to restrict pasting in my textareas, end user should not copy and paste the content, user should only type text in textarea.
How can I achieve this?
I just did this out of interest. I agree it's not the right thing to do, but I think it should be the op's decision... Also the code could easily be extended to add functionality, rather than take it away (like a more advanced clipboard, or Ctrl+S triggering a server-side save).
$(document).ready(function() {
var ctrlDown = false,
ctrlKey = 17,
cmdKey = 91,
vKey = 86,
cKey = 67;
$(document).keydown(function(e) {
if (e.keyCode == ctrlKey || e.keyCode == cmdKey) ctrlDown = true;
}).keyup(function(e) {
if (e.keyCode == ctrlKey || e.keyCode == cmdKey) ctrlDown = false;
});
$(".no-copy-paste").keydown(function(e) {
if (ctrlDown && (e.keyCode == vKey || e.keyCode == cKey)) return false;
});
// Document Ctrl + C/V
$(document).keydown(function(e) {
if (ctrlDown && (e.keyCode == cKey)) console.log("Document catch Ctrl+C");
if (ctrlDown && (e.keyCode == vKey)) console.log("Document catch Ctrl+V");
});
});
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<h3>Ctrl+c Ctrl+v disabled</h3>
<textarea class="no-copy-paste"></textarea>
<br><br>
<h3>Ctrl+c Ctrl+v allowed</h3>
<textarea></textarea>
Also just to clarify, this script requires the jQuery library.
Codepen demo
EDIT: removed 3 redundant lines (involving e.which) thanks to Tim Down's suggestion (see comments)
EDIT: added support for Macs (CMD key instead of Ctrl)
With jquery you can easy detect copy, paste, etc by binding the function:
$("#textA").bind('copy', function() {
$('span').text('copy behaviour detected!')
});
$("#textA").bind('paste', function() {
$('span').text('paste behaviour detected!')
});
$("#textA").bind('cut', function() {
$('span').text('cut behaviour detected!')
});
More information here: http://www.mkyong.com/jquery/how-to-detect-copy-paste-and-cut-behavior-with-jquery/
While it can be annoying when used as an anti-piracy measure, I can see there might be some instances where it'd be legitimate, so:
function disableCopyPaste(elm) {
// Disable cut/copy/paste key events
elm.onkeydown = interceptKeys
// Disable right click events
elm.oncontextmenu = function() {
return false
}
}
function interceptKeys(evt) {
evt = evt||window.event // IE support
var c = evt.keyCode
var ctrlDown = evt.ctrlKey||evt.metaKey // Mac support
// Check for Alt+Gr (http://en.wikipedia.org/wiki/AltGr_key)
if (ctrlDown && evt.altKey) return true
// Check for ctrl+c, v and x
else if (ctrlDown && c==67) return false // c
else if (ctrlDown && c==86) return false // v
else if (ctrlDown && c==88) return false // x
// Otherwise allow
return true
}
I've used event.ctrlKey rather than checking for the key code as on most browsers on Mac OS X Ctrl/Alt "down" and "up" events are never triggered, so the only way to detect is to use event.ctrlKey in the e.g. c event after the Ctrl key is held down. I've also substituted ctrlKey with metaKey for macs.
Limitations of this method:
Opera doesn't allow disabling right click events
Drag and drop between browser windows can't be prevented as far as I know.
The edit->copy menu item in e.g. Firefox can still allow copy/pasting.
There's also no guarantee that for people with different keyboard layouts/locales that copy/paste/cut are the same key codes (though layouts often just follow the same standard as English), but blanket "disable all control keys" mean that select all etc will also be disabled so I think that's a compromise which needs to be made.
If you use the ctrlKey property, you don't need to maintain state.
$(document).keydown(function(event) {
// Ctrl+C or Cmd+C pressed?
if ((event.ctrlKey || event.metaKey) && event.keyCode == 67) {
// Do stuff.
}
// Ctrl+V or Cmd+V pressed?
if ((event.ctrlKey || event.metaKey) && event.keyCode == 86) {
// Do stuff.
}
// Ctrl+X or Cmd+X pressed?
if ((event.ctrlKey || event.metaKey) && event.keyCode == 88) {
// Do stuff.
}
}
There's another way of doing this: onpaste, oncopy and oncut events can be registered and cancelled in IE, Firefox, Chrome, Safari (with some minor problems), the only major browser that doesn't allow cancelling these events is Opera.
As you can see in my other answer intercepting Ctrl+V and Ctrl+C comes with many side effects, and it still doesn't prevent users from pasting using the Firefox Edit menu etc.
function disable_cutcopypaste(e) {
var fn = function(evt) {
// IE-specific lines
evt = evt||window.event
evt.returnValue = false
// Other browser support
if (evt.preventDefault)
evt.preventDefault()
return false
}
e.onbeforepaste = e.onbeforecopy = e.onbeforecut = fn
e.onpaste = e.oncopy = e.oncut = fn
}
Safari still has some minor problems with this method (it clears the clipboard in place of cut/copy when preventing default) but that bug appears to have been fixed in Chrome now.
See also: http://www.quirksmode.org/dom/events/cutcopypaste.html and the associated test page http://www.quirksmode.org/dom/events/tests/cutcopypaste.html for more information.
Live Demo :
http://jsfiddle.net/abdennour/ba54W/
$(document).ready(function() {
$("#textA").bind({
copy : function(){
$('span').text('copy behaviour detected!');
},
paste : function(){
$('span').text('paste behaviour detected!');
},
cut : function(){
$('span').text('cut behaviour detected!');
}
});
});
Short solution for preventing user from using context menu, copy and cut in jQuery:
jQuery(document).bind("cut copy contextmenu",function(e){
e.preventDefault();
});
Also disabling text selection in CSS might come handy:
.noselect {
-webkit-touch-callout: none;
-webkit-user-select: none;
-khtml-user-select: none;
-moz-user-select: none;
-ms-user-select: none;
user-select: none;
}
Another approach (no plugin needed) it to just use ctrlKey property of the event object that gets passed in. It indicates if Ctrl was pressed at the time of the event, like this:
$(document).keypress("c",function(e) {
if(e.ctrlKey)
alert("Ctrl+C was pressed!!");
});
See also jquery: keypress, ctrl+c (or some combo like that).
You can use this code for rightclick, CTRL+C, CTRL+V, CTRL+X detect and prevent their action
$(document).bind('copy', function(e) {
alert('Copy is not allowed !!!');
e.preventDefault();
});
$(document).bind('paste', function() {
alert('Paste is not allowed !!!');
e.preventDefault();
});
$(document).bind('cut', function() {
alert('Cut is not allowed !!!');
e.preventDefault();
});
$(document).bind('contextmenu', function(e) {
alert('Right Click is not allowed !!!');
e.preventDefault();
});
instead of onkeypress, use onkeydown.
<input type="text" onkeydown="if(event.ctrlKey && event.keyCode==86){return false;}" name="txt">
If anyone is interested in a simple vanilla JavaScript approach, see below.
Fiddle Link: DEMO
let ctrlActive = false;
let cActive = false;
let vActive = false
document.body.addEventListener('keyup', event => {
if (event.key == 'Control') ctrlActive = false;
if (event.code == 'KeyC') cActive = false;
if (event.code == 'KeyV') vActive = false;
})
document.body.addEventListener('keydown', event => {
if (event.key == 'Control') ctrlActive = true;
if (ctrlActive == true && event.code == 'KeyC') {
// this disables the browsers default copy functionality
event.preventDefault()
// perform desired action(s) here...
console.log('The CTRL key and the C key are being pressed simultaneously.')
}
if (ctrlActive == true && event.code == 'KeyV') {
// this disables the browsers default paste functionality
event.preventDefault()
// perform desired action(s) here...
console.log('The CTRL key and the V key are being pressed simultaneously.')
}
})
The code above would disable the default copy in the browser. If you'd like keep the copy functionality in the browser, just comment out this bit: event.preventDefault() and you can then run any desired actions while allowing the user to copy content.
I wrote a jQuery plugin, which catches keystrokes. It can be used to enable multiple language script input in html forms without the OS (except the fonts). Its about 300 lines of code, maybe you like to take a look:
http://miku.github.com/jquery-retype
Generally, be careful with such kind of alterations. I wrote the plugin for a client because other solutions weren't available.
Don't forget that, while you might be able to detect and block Ctrl+C/V, you can still alter the value of a certain field.
Best example for this is Chrome's Inspect Element function, this allows you to change the value-property of a field.
A hook that allows for overriding copy events, could be used for doing the same with paste events. The input element cannot be display: none; or visibility: hidden; sadly
export const useOverrideCopy = () => {
const [copyListenerEl, setCopyListenerEl] = React.useState(
null as HTMLInputElement | null
)
const [, setCopyHandler] = React.useState<(e: ClipboardEvent) => void | null>(
() => () => {}
)
// appends a input element to the DOM, that will be focused.
// when using copy/paste etc, it will target focused elements
React.useEffect(() => {
const el = document.createElement("input")
// cannot focus a element that is not "visible" aka cannot use display: none or visibility: hidden
el.style.width = "0"
el.style.height = "0"
el.style.opacity = "0"
el.style.position = "fixed"
el.style.top = "-20px"
document.body.appendChild(el)
setCopyListenerEl(el)
return () => {
document.body.removeChild(el)
}
}, [])
// adds a event listener for copying, and removes the old one
const overrideCopy = (newOverrideAction: () => any) => {
setCopyHandler((prevCopyHandler: (e: ClipboardEvent) => void) => {
const copyHandler = (e: ClipboardEvent) => {
e.preventDefault()
newOverrideAction()
}
copyListenerEl?.removeEventListener("copy", prevCopyHandler)
copyListenerEl?.addEventListener("copy", copyHandler)
copyListenerEl?.focus() // when focused, all copy events will trigger listener above
return copyHandler
})
}
return { overrideCopy }
}
Used like this:
const customCopyEvent = () => {
console.log("doing something")
}
const { overrideCopy } = useOverrideCopy()
overrideCopy(customCopyEvent)
Every time you call overrideCopy it will refocus and call your custom event on copy.
Another simple way using Jquery:
$(document).keydown( function(e)
{
if (e.ctrlKey && e.key == 'c')
{
console.log('got ctrl c');
}
else if (e.ctrlKey && e.key == 'v')
{
console.log('got ctrl v');
}
});
element.addEventListener('keydown', function (e) {
if (e.key == 'c' && e.ctrlKey) {
e.preventDefault(); // prevent from copying
}
if (e.key == 'v' && e.ctrlKey) {
e.preventDefault(); // prevent from pasting
}
}
i already have your problem and i solved it by the following code .. that accept only numbers
$('#<%= mobileTextBox.ClientID %>').keydown(function(e) {
///// e.which Values
// 8 : BackSpace , 46 : Delete , 37 : Left , 39 : Rigth , 144: Num Lock
if (e.which != 8 && e.which != 46 && e.which != 37 && e.which != 39 && e.which != 144
&& (e.which < 96 || e.which > 105 )) {
return false;
}
});
you can detect Ctrl id e.which == 17
Important note
I was using e.keyCode for a while and i detected that when i press Ctrl+., This attribute returns a wrong number, 190, while the ascii code of . is 46!
So you should use e.key.toUpperCase().charCodeAt(0) instead of e.keyCode.
$(document).keydown(function(event) {
let keyCode = e.key.toUpperCase().charCodeAt(0);
...
}
You can listen to the keypress event, and halt the default event (entering the text) if it matches the specific keycodes
There is some ways to prevent it.
However the user will be always able to turn the javascript off or just look on the source code of the page.
Some examples (require jQuery)
/**
* Stop every keystroke with ctrl key pressed
*/
$(".textbox").keydown(function(){
if (event.ctrlKey==true) {
return false;
}
});
/**
* Clear all data of clipboard on focus
*/
$(".textbox").focus(function(){
if ( window.clipboardData ) {
window.clipboardData.setData('text','');
}
});
/**
* Block the paste event
*/
$(".textbox").bind('paste',function(e){return false;});
Edit: How Tim Down said, this functions are all browser dependents.
My users would like to be able to hit Ctrl+S to save a form. Is there a good cross-browser way of capturing the Ctrl+S key combination and submit my form?
App is built on Drupal, so jQuery is available.
This works for me (using jquery) to overload Ctrl+S, Ctrl+F and Ctrl+G:
$(window).bind('keydown', function(event) {
if (event.ctrlKey || event.metaKey) {
switch (String.fromCharCode(event.which).toLowerCase()) {
case 's':
event.preventDefault();
alert('ctrl-s');
break;
case 'f':
event.preventDefault();
alert('ctrl-f');
break;
case 'g':
event.preventDefault();
alert('ctrl-g');
break;
}
}
});
$(window).keypress(function(event) {
if (!(event.which == 115 && event.ctrlKey) && !(event.which == 19)) return true;
alert("Ctrl-S pressed");
event.preventDefault();
return false;
});
Key codes can differ between browsers, so you may need to check for more than just 115.
You could use a shortcut library to handle the browser specific stuff.
shortcut.add("Ctrl+S",function() {
alert("Hi there!");
});
This jQuery solution works for me in Chrome and Firefox, for both Ctrl+S and Cmd+S.
$(document).keydown(function(e) {
var key = undefined;
var possible = [ e.key, e.keyIdentifier, e.keyCode, e.which ];
while (key === undefined && possible.length > 0)
{
key = possible.pop();
}
if (key && (key == '115' || key == '83' ) && (e.ctrlKey || e.metaKey) && !(e.altKey))
{
e.preventDefault();
alert("Ctrl-s pressed");
return false;
}
return true;
});
This one worked for me on Chrome...
for some reason event.which returns a capital S (83) for me, not sure why (regardless of the caps lock state) so I used fromCharCode and toLowerCase just to be on the safe side
$(document).keydown(function(event) {
//19 for Mac Command+S
if (!( String.fromCharCode(event.which).toLowerCase() == 's' && event.ctrlKey) && !(event.which == 19)) return true;
alert("Ctrl-s pressed");
event.preventDefault();
return false;
});
If anyone knows why I get 83 and not 115, I will be happy to hear, also if anyone tests this on other browsers I'll be happy to hear if it works or not
I combined a few options to support FireFox, IE and Chrome. I've also updated it to better support mac
// simply disables save event for chrome
$(window).keypress(function (event) {
if (!(event.which == 115 && (navigator.platform.match("Mac") ? event.metaKey : event.ctrlKey)) && !(event.which == 19)) return true;
event.preventDefault();
return false;
});
// used to process the cmd+s and ctrl+s events
$(document).keydown(function (event) {
if (event.which == 83 && (navigator.platform.match("Mac") ? event.metaKey : event.ctrlKey)) {
event.preventDefault();
save(event);
return false;
}
});
$(document).keydown(function(e) {
if ((e.key == 's' || e.key == 'S' ) && (e.ctrlKey || e.metaKey))
{
e.preventDefault();
alert("Ctrl-s pressed");
return false;
}
return true;
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
Try pressing ctrl+s somewhere.
This is an up-to-date version of #AlanBellows's answer, replacing which with key. It also works even with Chrome's capital key glitch (where if you press Ctrl+S it sends capital S instead of s). Works in all modern browsers.
I would like Web applications to not override my default shortcut keys, honestly. Ctrl+S already does something in browsers. Having that change abruptly depending on the site I'm viewing is disruptive and frustrating, not to mention often buggy. I've had sites hijack Ctrl+Tab because it looked the same as Ctrl+I, both ruining my work on the site and preventing me from switching tabs as usual.
If you want shortcut keys, use the accesskey attribute. Please don't break existing browser functionality.
#Eevee: As the browser becomes the home for richer and richer functionality and starts to replace desktop apps, it's just not going to be an option to forgo the use of keyboard shortcuts. Gmail's rich and intuitive set of keyboard commands was instrumental in my willingness to abandon Outlook. The keyboard shortcuts in Todoist, Google Reader, and Google Calendar all make my life much, much easier on a daily basis.
Developers should definitely be careful not to override keystrokes that already have a meaning in the browser. For example, the WMD textbox I'm typing into inexplicably interprets Ctrl+Del as "Blockquote" rather than "delete word forward". I'm curious if there's a standard list somewhere of "browser-safe" shortcuts that site developers can use and that browsers will commit to staying away from in future versions.
To Alan Bellows answer: !(e.altKey) added for users who use AltGr when typing (e.g Poland). Without this pressing AltGr+S will give same result as Ctrl+S
$(document).keydown(function(e) {
if ((e.which == '115' || e.which == '83' ) && (e.ctrlKey || e.metaKey) && !(e.altKey))
{
e.preventDefault();
alert("Ctrl-s pressed");
return false;
}
return true; });
I like this little plugin. It needs a bit more cross browser friendliness though.
This should work (adapted from https://stackoverflow.com/a/8285722/388902).
var ctrl_down = false;
var ctrl_key = 17;
var s_key = 83;
$(document).keydown(function(e) {
if (e.keyCode == ctrl_key) ctrl_down = true;
}).keyup(function(e) {
if (e.keyCode == ctrl_key) ctrl_down = false;
});
$(document).keydown(function(e) {
if (ctrl_down && (e.keyCode == s_key)) {
alert('Ctrl-s pressed');
// Your code
return false;
}
});
example:
shortcut.add("Ctrl+c",function() {
alert('Ok...');
}
,{
'type':'keydown',
'propagate':false,
'target':document
});
usage
<script type="text/javascript" src="js/shortcut.js"></script>
link for download: http://www.openjs.com/scripts/events/keyboard_shortcuts/#
This Plugin Made by me may be helpful.
Plugin
You can use this plugin you have to supply the key Codes and function to be run like this
simulatorControl([17,83], function(){
console.log('You have pressed Ctrl+Z');
});
In the code i have displayed how to perform for Ctrl+S. You will get Detailed Documentation On the link. Plugin is in JavaScript Code section Of my Pen on Codepen.
I solved my problem on IE, using an alert("With a message") to prevent default Behavior:
window.addEventListener("keydown", function (e) {
if(e.ctrlKey || e.metaKey){
e.preventDefault(); //Good browsers
if (navigator.userAgent.indexOf('MSIE') !== -1 || navigator.appVersion.indexOf('Trident/') > 0) { //hack for ie
alert("Please, use the print button located on the top bar");
return;
}
}
});
This was my solution, which is much easier to read than other suggestions here, can easily include other key combinations, and has been tested on IE, Chrome, and Firefox:
$(window).keydown(function(evt) {
var key = String.fromCharCode(evt.keyCode).toLowerCase();
switch(key) {
case "s":
if(evt.ctrlKey || evt.metaKey) {
fnToRun();
evt.preventDefault(true);
return false;
}
break;
}
return true;
});
A lot of answers in this thread mention e.which or e.Keycode which are not recommended nowadays according to MDN and https://keyjs.dev/. Moreover, the most-rated answer looks a little bit overdone since it also brings other hotkeys which leads to usage of switch. I did not check the third-party libraries, but I always try to use as few third-party libraries as possible.
Here's my solution (since you mentioned jQuery in your question):
$(document).keydown(function(e) {
if (e.ctrlKey && e.key == "s" || e.metaKey && e.key == "s") {
myFunction();
e.preventDefault();
}
});
The e.metaKey is here because of Mac devices.
The myFunction(); line is where you specify your function. The e.preventDefault(); line is here to prevent opening of the "Saveā¦" window. If you want to keep it for some reason, feel free to remove this line.