11

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.

Brian Tompsett - 汤莱恩
  • 5,753
  • 72
  • 57
  • 129
coderunner
  • 925
  • 1
  • 18
  • 33
  • 1
    The 2nd one works for me. What browser are you using and which version is it? – Antony Jan 28 '13 at 12:29
  • I tried it on chrome,FF and IE 8,9.I believe if I alert it brings the default window with it!!If I do a `console.log`,it doesn't bring up the window!! :P **Why is it so?** – coderunner Jan 28 '13 at 12:30

5 Answers5

21

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)

Cerbrus
  • 70,800
  • 18
  • 132
  • 147
  • Yes Cerbus I did the same!But for alert it brings up the window(**I had tried alert first as examples had it**).But for `console.log`,it seems to work fine!! Any problem with the script or it is the default behaviour?? :P – coderunner Jan 28 '13 at 12:34
  • Ah, then the problem was that the `alert` was pausing your code before it could stop the save dialog from showing. – Cerbrus Jan 28 '13 at 12:36
  • Yes got your point Cerbus!!Thank you!!I am going the jquery way as I am not sure i would need any further short cuts in the application!I was a bit stupid there!! :P – coderunner Jan 28 '13 at 12:39
  • 1
    @coderunner: you are aware that my code is exactly the same as the answer you accepted, right? (Except that I posted it earlier). Only the other answer used the old `.bind()` function, which the guys over at jQuery suggest not to use any more. The `'ctrl+s'` seems to be data that isn't used anywhere, either. – Cerbrus Jan 28 '13 at 12:44
  • @Cerbus I have not accepted it for the answer,I have used my own implementation.The answer was accepted based on the explanation added in it(that was what I was looking for).I was confused with the alert part.I **upvoted** your answer with due respect.Please don't mind, no offence.Both the answers were equally quick and informative and looking forward for your support. – coderunner Jan 28 '13 at 12:49
  • 1
    [Make sure that besides working for you, the answer is really good practice. Sometimes after the answer gets accepted, another comes in, uncovering the fact that previous one was in fact a bad hack.](http://meta.stackexchange.com/a/5235/203057). That's all I'll say. – Cerbrus Jan 28 '13 at 12:52
  • Thank you for the info.Will keep that in mind!!Have changed it for the community. – coderunner Jan 28 '13 at 12:57
  • I think you can also improve your solution using `switch()` function and expand your answer for every other button, like `Ctrl + B`, `Ctrl + I` and ... – Shafizadeh Feb 02 '16 at 07:57
  • 1
    That would be past the scope of the question. – Cerbrus Feb 02 '16 at 08:58
18

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);
coderunner
  • 925
  • 1
  • 18
  • 33
4

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 ...
    }
})
Xenxier
  • 431
  • 4
  • 7
3

As of 2017, instead of using e.keyCode === 83 you should use e.key === 's' as the former is deprecated.

carkod
  • 1,844
  • 19
  • 32
1

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.

Rohit Patel
  • 459
  • 2
  • 14
  • 2
    [As of jQuery 1.7, the .on() method is the preferred method for attaching event handlers to a document.](http://api.jquery.com/bind/). Also, you're passing optional eventData that isn't used. – Cerbrus Jan 28 '13 at 12:45