0

I'm trying to catch both Ctrl-S and Cmd-S on browsers for cross-OS Compatibility of my web app. I saw a thread about how to do that here: jquery keypress event for cmd+s AND ctrl+s

I have the following snippet in my code:

$(document).keypress(function(event) {
  if (event.which == 115 && (event.ctrlKey||event.metaKey)|| (event.which == 19)) {
    event.preventDefault();
    save();
    return false;
  }
  return true;
});

where save() is a JavaScript function that will send an AJAX request in the future, but just has alert('Saved!'); for now.

However, although this catches Ctrl-S, it doesn't catch Cmd-S on Chrome, instead just opening the save webpage dialog like usual. I saw that someone else on that page had the same problem, but I didn't see a solution for it.

Thanks in advance!

Xyz
  • 5,955
  • 5
  • 40
  • 58
Neelu S
  • 47
  • 1
  • 11
  • Also to note, `the keypress event isn't covered by any official specification, the actual behavior encountered when using it may differ across browsers, browser versions, and platforms.` (from official [jQuery doc for `keypress`](https://api.jquery.com/keypress/)). You might want to consider not using `keypress` at all. – filoxo Sep 14 '16 at 20:14
  • @filoxo Thanks for letting me know :) – Neelu S Sep 15 '16 at 06:10

2 Answers2

2

So ingenious!!! Bravo @Sam0.

For beginners who'd like simple JavaScript version, with no JQuery (even though when you catch the thing, $() just allows you to handily designate a CSS selector), here's the script:

/**
* CMD+S/CTRL+S
* Function listens first to cmd or ctrl keys.
* Metaflag variable becomes true if one of those keys is pressed.
* If key "s" is then listened - before 100ms delay -, it launches your    
  instructions. 
* Without timer, "s" could happen (e.g.) 1 hour after alteration key pressed,     
* even if your just type "s" in a text. Timer is a trick to avoid this.
*/

(function(){
  var metaflag = false;
  document.addEventListener('keydown',function(event) {
    if (event.ctrlKey||event.metaKey || event.which === 19) {
      //      ctrl           cmd(mac)         break/pause key(?)
      metaflag = true;
      timer = Date.now();
    }
    if(metaflag && event.which === 83 && Date.now()-timer<100){
      //                 "S"                                //100ms
      event.preventDefault(); // maybe not necessary
      //...Your instructions...
      metaflag = false;
    }
  });
})();
1

I think keypress as you have it doesn't register metakeys in the quite the same way, see: Diffrence between keyup keydown keypress and input events here's a fiddle that seems to work using keydown, and then capturing each in sequence. Hope it helps?

var metaflag = false;

$(document).on({
 keydown: function(event) {
    if (event.ctrlKey||event.metaKey || event.which === 19) {
      event.preventDefault();
      $('.monitor').text('key '+event.which);
      metaflag = true;
    }
   if( metaflag && event.which === 83 ){ // 83 = s?
      event.preventDefault(); // maybe not necessary
      $('.display').text('saving?');
      metaflag = false;
    }
  }
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>

<div class='monitor'></div>
<div class='display'></div>
Community
  • 1
  • 1
Sam0
  • 1,459
  • 1
  • 11
  • 13