4

What am I doing wrong? It seems that the array is not cleared after the function was called.

If you press first ctrl+c and then ctrl+alt+c the second function will not called (only if you press it a second time).

var key = function (keys, fn) {
  var arr = [];
  $(document).on({
    keydown: function (e) {
      arr.push(e.which);
      if (arr.join(', ') === keys) {
        fn(e);
        arr = [];
      }
    },
    keyup: function (e) {
      arr = [];
    }
  });
};

// ctrl + c
key('17, 67', function (e) {
  alert('ctrl+c');
});

// ctrl + alt + c
key('17, 18, 67', function () {
  alert('ctrl+alt+c');
});

Here's a fiddle.

6
  • NB: this is not a good way of trapping key sequences. 1. it registers an additional keydown and keyup handler for every sequence - that doesn't scale 2. ctrl-alt-N is normally treated the same as alt-ctrl-N Commented Jan 16, 2013 at 13:41
  • Plus there's the problem when you hold down a key and it ends up in the array multiple times, as well as not registering holding down ctrl and pressing 'c' multiple times, not just once and then lifting all fingers. Commented Jan 16, 2013 at 13:43
  • @Archer you're completely correct! Any ideas to get around this problem and still be simple? Commented Jan 16, 2013 at 13:46
  • @Alnitak Your first point is clear. But can you explain the 2nd one a bit? For example if i press c+ctrl it does not copy anything ;) Commented Jan 16, 2013 at 13:48
  • @yckart it's different for single meta key sequences - I was talking about sequences with multiple meta keys. You always press the non-meta key last, but it shouldn't matter which order you press the meta keys. Commented Jan 16, 2013 at 13:52

2 Answers 2

2

The problem in your code isn't the array.

Your keyup is not being called because you release the key when you see the alert window

Check the same code working in here: http://jsfiddle.net/WucCQ/1/ - Watch the console log

var key = function (keys, fn) {
  var arr = [];
  $(document).on({
    keydown: function (e) {
      arr.push(e.which);
      if (arr.join(', ') === keys) {
        fn(e);
        arr = [];
      }
    },
    keyup: function (e) {
      arr = [];
    }
  });
};

// ctrl + c
key('17, 67', function (e) {
  console.log('ctrl+c');
});

// ctrl + alt + c
key('17, 18, 67', function () {
  console.log('ctrl+alt+c');
});
Sign up to request clarification or add additional context in comments.

Comments

2

EDIT: This code is not good as appeared. It will not see the difference between Ctrl+C and Cltrl+C+V!

Try this code:

var key = function (keys, fn) {  
  $(document).on({
    keydown: function (e) {
      var arr = [];
      if(e.ctrlKey)
        arr.push("17");
      if(e.altKey)
        arr.push("18");
      arr.push(e.which);
      if (arr.join(', ') === keys) {
        fn(e);        
      }
    }
  });
};

// ctrl + c
key('17, 67', function (e) {
  alert('ctrl+c');
});

// ctrl + alt + d
key('17, 18, 68', function () {
  alert('ctrl+alt+c');
});

Instead of collecting pressed keys into global array, you can check if it is pressed when keydown event happens. This works fine for me: http://fiddle.jshell.net/27WGw/2/ (Note that I changed Ctrl+Alt+c to Ctrl+Alt+d as the first one is a global hotkey on my machine)

6 Comments

Not really practical, a little too undynamic
What do you mean under undynamic?
@yckart - I think you've misunderstood something. This works perfectly.
@Archer Not really... press something like ctrl+v+c results in true.
@yckart He's answered the question, as asked, perfectly. If there's an issue with the answer then you need to clarify the question :)
|

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.