[javascript] Best cross-browser method to capture CTRL+S with JQuery?

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 question is related to javascript jquery

The answer is


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;
    }
}); 

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;
     }
});

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;
        }
    }
});

You could use a shortcut library to handle the browser specific stuff.

shortcut.add("Ctrl+S",function() {
    alert("Hi there!");
});

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/#


@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.


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);
    //ctrl+s
    if (key.toLowerCase() === "s" && evt.ctrlKey) {
        fnToRun();
        evt.preventDefault(true);
        return false;
    }
    return true;
});

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.


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 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;
    }
}); 

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.


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;
        }
    }
});

@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.


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;
        }
    }
});

I like this little plugin. It needs a bit more cross browser friendliness though.


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; });

@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.


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;
     }
});

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


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.


You could use a shortcut library to handle the browser specific stuff.

shortcut.add("Ctrl+S",function() {
    alert("Hi there!");
});

@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; });

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;
}); 

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;
        }
    }
});

You could use a shortcut library to handle the browser specific stuff.

shortcut.add("Ctrl+S",function() {
    alert("Hi there!");
});

_x000D_
_x000D_
$(document).keydown(function(e) {_x000D_
    if ((e.key == 's' || e.key == 'S' ) && (e.ctrlKey || e.metaKey))_x000D_
    {_x000D_
        e.preventDefault();_x000D_
        alert("Ctrl-s pressed");_x000D_
        return false;_x000D_
    }_x000D_
    return true;_x000D_
}); 
_x000D_
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>_x000D_
Try pressing ctrl+s somewhere.
_x000D_
_x000D_
_x000D_

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.


You could use a shortcut library to handle the browser specific stuff.

shortcut.add("Ctrl+S",function() {
    alert("Hi there!");
});

I like this little plugin. It needs a bit more cross browser friendliness though.


_x000D_
_x000D_
$(document).keydown(function(e) {_x000D_
    if ((e.key == 's' || e.key == 'S' ) && (e.ctrlKey || e.metaKey))_x000D_
    {_x000D_
        e.preventDefault();_x000D_
        alert("Ctrl-s pressed");_x000D_
        return false;_x000D_
    }_x000D_
    return true;_x000D_
}); 
_x000D_
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>_x000D_
Try pressing ctrl+s somewhere.
_x000D_
_x000D_
_x000D_

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.


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);
    //ctrl+s
    if (key.toLowerCase() === "s" && evt.ctrlKey) {
        fnToRun();
        evt.preventDefault(true);
        return false;
    }
    return true;
});

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/#


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.


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