Создание комбинаций клавиш с помощью jQuery / JavaScript - PullRequest
7 голосов
/ 02 ноября 2010

Мне любопытно, как я, используя следующий код плагина jQuery, который я пишу в нижней части этого вопроса, мог реализовать комбинации клавиш.До сих пор он работает так, что позволяет пользователю создавать ключевые команды, просто выполняя обычный jQuery-подобный синтаксис и предоставляя событие для ключевой команды, например:

$(window).jkey('a',function(){
   alert('you pressed the a key!');
});

или

$(window).jkey('b c d',function(){
   alert('you pressed either the b, c, or d key!');
});

и, наконец, я хочу сделать это, но не могу понять:

$(window).jkey('alt+n',function(){
   alert('you pressed alt+n!');
});

Я знаю, как сделать это вне плагина (на keyup установите var false и на keydownустановите var true и проверьте, является ли var true, когда вы нажимаете другую клавишу), но я не знаю, как это сделать, когда вы не знаете, какие клавиши будут нажиматься и сколько.Как мне добавить эту поддержку?Я хочу иметь возможность позволить им делать такие вещи, как alt+shift+a или a+s+d+f, если они захотят.Я просто не могу понять, как это реализовать.Есть идеи?

Я собираюсь выпустить это как плагин с открытым исходным кодом, и я хотел бы дать тому, кто дает мне право, работать, ответить на некоторые вопросы в блоге и в коде, который он сам.Заранее спасибо!

(function($) {
  $.fn.jkey = function(keyCombo,callback) {
    if(keyCombo.indexOf(' ') > -1){ //If multiple keys are selected
        var keySplit = keyCombo.split(' ');
    }
    else{ //Else just store this single key
        var keySplit = [keyCombo];
    }
    for(x in keySplit){ //For each key in the array...

        if(keySplit[x].indexOf('+') > -1){
            //Key selection by user is a key combo... what now?
        }
        else{
            //Otherwise, it's just a normal, single key command
        }

        switch(keySplit[x]){
            case 'a':
                keySplit[x] = 65;
                break;
            case 'b':
                keySplit[x] = 66;
                break;
            case 'c':
                keySplit[x] = 67;
                break;
            //And so on for all the rest of the keys
        }
    }
    return this.each(function() {
        $this = $(this);
        $this.keydown(function(e){
            if($.inArray(e.keyCode, keySplit) > -1){ //If the key the user pressed is matched with any key the developer set a key code with...
                if(typeof callback == 'function'){ //and they provided a callback function
                    callback(); //trigger call back and...
                    e.preventDefault(); //cancel the normal
                }
            }
        });
    });
  }
})(jQuery);

Ответы [ 4 ]

5 голосов
/ 04 ноября 2010

Используйте нажатие клавиши вместо keyup / keydown, поскольку последние два не точно передают код клавиши ( ссылка , см. Последний абзац). В этом случае вы можете ссылаться на логические свойства altKey ctrlKey и shiftKey объекта события ...

$(document).keypress(function(e) {
  var key = String.fromCharCode(e.which);
  var alt = e.altKey;
  var ctrl = e.ctrlKey
  var shift = e.shiftKey;
  alert("Key:" + key + "\nAlt:" + alt + "\nCtrl:" + ctrl + "\nShift:" + shift);
});

Кроме того, вы можете использовать String.fromCharCode для перевода кода ключа в реальную букву.

Вы не можете перехватывать несколько клавиш, кроме сочетаний клавиш Ctrl, Alt и Shift. Вы просто не можете сделать это в одном событии. Так что выбросьте a+s+d+f идею в окно.

Примечание. Очевидно, что существуют определенные комбинации клавиш, которые используются браузером. Например, Alt + F обычно вызывает меню «Файл» в Windows. Ctrl + N обычно запускает новое окно / вкладку. не пытайтесь переопределить любую из этих комбинаций.

Вот демоверсия live для вашего удовольствия от тестирования.

2 голосов
/ 05 ноября 2010

Вот что я придумал.По сути, я создал объект JSON, в котором хранятся все коды клавиш.Затем я заменяю все предоставленные ключи кодами.Если клавиши используют «+» для создания комбинации клавиш, я затем создаю из нее массив кодов.

Затем мы создаем другой массив, в котором хранятся все клавиши, которые были нажаты (добавление keyDownэлемент, keyUp удаляет его).На keyDown мы проверяем, является ли это клавишей или комбинацией клавиш.Если это комбо, мы проверяем его по всем активным в настоящий момент нажатиям клавиш.Если они все совпадают, мы выполняем обратный вызов.

Это будет работать с любым количеством комбинаций клавиш.Единственный раз, когда я увидел, что это не работает, это когда вы используете функцию «alert ()» для отображения сообщения в комбинации клавиш, потому что он больше не удаляет элементы из массива нажатия активной клавиши.

(function($) { 
  $.fn.jkey = function(keyCombo,callback) {

    // Save the key codes to JSON object
    var keyCodes = { 
      'a'   : 65,
      'b'   : 66,
      'c'   : 67,
      'alt' : 18
    };

    var x = '';
    var y = '';

    if(keyCombo.indexOf(' ') > -1){ //If multiple keys are selected
        var keySplit = keyCombo.split(' ');
    }
    else{ //Else just store this single key
        var keySplit = [keyCombo];
    }

    for(x in keySplit){ //For each key in the array...

      if(keySplit[x].indexOf('+') > -1){
        //Key selection by user is a key combo
        // Create a combo array and split the key combo
        var combo = Array();
        var comboSplit = keySplit[x].split('+');

        // Save the key codes for each element in the key combo
        for(y in comboSplit){
          combo[y] = keyCodes[ comboSplit[y] ];
        }

        keySplit[x] = combo;

      } else {
        //Otherwise, it's just a normal, single key command
        keySplit[x] = keyCodes[ keySplit[x] ];
      }

    }

    return this.each(function() {
        $this = $(this);

        // Create active keys array
        // This array will store all the keys that are currently being pressed
        var activeKeys = Array();

        $this.keydown(function(e){

          // Save the current key press
          activeKeys[ e.keyCode ] = e.keyCode;

          if($.inArray(e.keyCode, keySplit) > -1){ // If the key the user pressed is matched with any key the developer set a key code with...

            if(typeof callback == 'function'){ //and they provided a callback function
              callback(); //trigger call back and...
              e.preventDefault(); //cancel the normal
            }

          } else { // Else, the key did  not match which means it's either a key combo or just dosn't exist

            // Check if the individual items in the key combo match what was pressed
            for(x in keySplit){
              if($.inArray(e.keyCode, keySplit[x]) > -1){

                // Initiate the active variable
                var active = 'unchecked';

                // All the individual keys in the combo with the keys that are currently being pressed
                for(y in keySplit[x]) {
                  if(active != false) {
                    if($.inArray(keySplit[x][y], activeKeys) > -1){
                      active = true;
                    } else {
                      active = false;
                    }
                  }
                }

                // If all the keys in the combo are being pressed, active will equal true
                if(active === true){
                  if(typeof callback == 'function'){ //and they provided a callback function
                    callback(); //trigger call back and...
                    e.preventDefault(); //cancel the normal
                  }
                }
              }
            }

          } // end of if in array

        }).keyup(function(e) {
          // Remove the current key press
          activeKeys[ e.keyCode ] = '';
        });

    });

  }
})(jQuery);
0 голосов
/ 01 мая 2012

Если вы ищете что-то, что позволит пользователю легко вводить и определять комбинации клавиш с помощью простого поля ввода, я написал плагин, который сделает это за вас: http://suan.github.com/jquery-keycombinator/

0 голосов
/ 04 ноября 2010

Это просто выстрел в темноте, но, возможно, он поможет вам выбрать правильный путь.

Если возможно, чтобы эта функция распознала шестнадцатеричное значение для введенной вами клавиши вместо литералаключом (например, 0x6E для буквы 'n'), вы можете получить то, что "alt + n" переводит в шестнадцатеричное значение, и заставить функцию искать это значение.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...