Подтвердить что ты не робот

Обнаружение нескольких ключей в одном событии нажатия клавиши в jQuery

Можно ли комбинировать смесь нажатия клавиш для запуска одного события?

$(document).keyup(function(e){
    if (e.keyCode == 68 && e.keyCode == 69 && e.keyCode == 86) {
        alert('oh hai');
    }
});

Я пробовал его в Chrome, но событие не срабатывает.

Назовите меня сумасшедшим, но я пишу расширение Chrome и хочу нажимать клавиши D + E + V, чтобы заставить его перейти в скрытый режим разработчика.

4b9b3361

Ответ 1

Если вы хотите обнаружить, что клавиши d, e и v были опущены одновременно, вы должны смотреть как keydown, так и keyup и сохранять карту которые не работают. Когда они все опущены, запустите свое событие.

Например: Живая копия | источник

var map = {68: false, 69: false, 86: false};
$(document).keydown(function(e) {
    if (e.keyCode in map) {
        map[e.keyCode] = true;
        if (map[68] && map[69] && map[86]) {
            // FIRE EVENT
        }
    }
}).keyup(function(e) {
    if (e.keyCode in map) {
        map[e.keyCode] = false;
    }
});

Я предполагаю, что вас не волнует, в каком порядке они были нажаты (так как это было бы болью, чтобы надежно нажать), пока они все в то же время в какой-то момент.

Ответ 2

Подобно Vega's... но проще

var down = {};
$(document).keydown(function(e) {
    down[e.keyCode] = true;
}).keyup(function(e) {
    if (down[68] && down[69] && down[86]) {
        alert('oh hai');
    }
    down[e.keyCode] = false;
});​

Ответ 3

Возможно, проще было бы упростить сочетание клавиш?

Как насчет чего-то вроде Shift + Alt + D? (Вероятно, вы не должны использовать контрольный ключ, потому что большинство браузеров уже так или иначе интерпретируют Ctrl + D)

Код для этого будет примерно таким:

if(e.shiftKey && e.altKey && e.keyCode == 68)
{
  alert('l33t!');
}

Ответ 4

Вам нужно будет захватить три ключевых события отдельно и запустить свое действие только после третьего.

var keys = {
        d: { code: 100, pressed: false, next: 'e' },
        e: { code: 101, pressed: false, next: 'v' },
        v: { code: 118, pressed: false, next: 'd' }
    },
    nextKey = 'd';

$(document).keypress(function(e) {
    if (e.keyCode === keys[nextKey].code) {
        keys[nextKey].pressed = true;
        nextKey = keys[nextKey].next;
    } else {
        keys.d.pressed = false;
        keys.e.pressed = false;
        keys.v.pressed = false;
        nextKey = 'd';
    }

    if (keys.d.pressed && keys.e.pressed && keys.v.pressed) {
        alert('Entering dev mode...');
    }
});​

Существует несколько способов сделать это, конечно. Этот пример не требует одновременного хранения ключей, просто введите их в порядок: d e v.

Если вы использовали это, вы можете увеличить его, чтобы очистить флаги pressed через некоторый промежуток времени.

Здесь рабочий пример.


Отказ от ответственности: я понимаю, что в первоначальном вопросе говорилось, что ключи должны быть "спрессованы". Это просто альтернатива, поскольку другие ответчики уже предоставили достаточные решения для нажатия клавиш вместе.

Ответ 5

Я попробовал три лучших ответа (начиная с этого поста), и никто из них не работал у меня. Они не reset клавиши.

Если бы у вас было 3 клавиши, огонь script, после того, как он выстрелил один раз - нажатие любой из трех клавиш запустило бы его снова.

Я только что написал этот script, и он работает очень хорошо. Он использует Shift + S для стрельбы, но вы можете легко изменить это. Он сбрасывается после нажатия комбинации.

var saveArray = new Array();
saveArray[0] = false;
saveArray[1] = false;

$(document).ready(function(){

    $(document).keydown(function (f){
        if (f.keyCode == 16) {
            saveArray[0] = true;
        }
    });

    $(document).keyup(function (g){
        if(g.which == 16){
            saveArray[0] = false;
        }
    });

    $(document).keydown(function (h){
        if (h.keyCode == 83) {
            saveArray[1] = true;
            if(saveArray[0] == true && saveArray[1] == true){
                saveArray[0] = false;
                saveArray[1] = false;
                keypressSaveFunction();
            }
        }
    });

    $(document).keyup(function (i){
        if (i.which == 83) {
            saveArray[1] = false;
        }
    });
});

    function keypressSaveFunction(){
        alert("You pressed Shift+S");
    }

Fiddle: http://jsfiddle.net/9m8yswwo/13/

Ответ 6

если я хорошо понял: пример скрипка, http://jsfiddle.net/gAtTk/ (посмотрите на консоль js)

этот код позволит вам ввести слово "dev" (и в этом примере в конце удаляется событие keyup)

(function(seq) {
    var tmp = seq.slice();
    $(document).on("keyup.entersequence", function(e){
        if (!(e.keyCode === tmp.pop())) {
           tmp = seq.slice();
        }
        else {
           console.log(e.keyCode);  
            if (!tmp.length) {
               console.log('end');
               $(document).off("keyup.entersequence");
            }
        }
    });
}([68,69,86].reverse()));

Ответ 7

Вы должны использовать события keydown и keyup, чтобы обрабатывать более одного ключа "одновременно".

input.on("keydown", function (e) {
                        if (e.which == 17) {
                            isCtrl = true; // Ctrl
                            return;
                        }

                        /* Ctrl and "c" */
                        if (isCtrl && e.which == 67) {
                            //some code 
                        }
                    }).keyup(function (e) {
                        if (e.which == 17) {
                            isCtrl = false; // no Ctrl
                        }
                    });

Ответ 8

Немного более современное решение, использует функции стрелок и rest параметры:

const multipleKeypress = (function($document) {
  // Map of keys which are currently down.
  const keymap = {}
  // Update keymap on keydown and keyup events.
  $document.on(
    "keydown keyup"
    // If the key is down, assign true to the corresponding
    // propery of keymap, otherwise assign false.
   ,event => keymap[event.keyCode] = event.type === "keydown"
  )
  // The actual function.
  // Takes listener as the first argument,
  // rest of the arguments are key codes.
  return (listener, ...keys) =>
    $document.keydown(() => {
      // Check if every of the specified keys is down.
      if (keys.every(key => keymap[key]))
        listener(event)
    })
// Pass a jQuery document object to cache it.
}($(document)))

// Example usage:
multipleKeypress(() => console.log("pressed"), 68, 69, 86)

// Automatically focus the snippet result
window.focus()
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<p>Try pressing <kbd>d</kbd>, <kbd>e</kbd> and <kbd>v</kbd> at once.</p>

Ответ 9

Используйте этот код для запуска события несколькими нажатиями клавиш + Тайм-аут после 100 мс для предотвращения ошибок. В этом примере: если A, Z, E нажаты в течение периода времени 100 мс, событие будет запущено.

var map = {65:false,90:false,69:false}; //Modify keyCodes here
$(document).keydown(function(e){
    console.log(e.keyCode);
    map[e.keyCode] = e.keyCode in map ? true : map[e.keyCode] || false;
    var result = Object.keys(map).filter(function(key){
        return map[key];
    }).length === Object.keys(map).length ? true : false;
    if(result){
        //Your event here
        Object.keys(map).forEach(function(key){
            map[key] = false;
        });
    }
    setTimeout(function(){
        map[e.keyCode] = false;
    },100);
});

Ответ 10

Если вам небезразличен порядок, а также нужно удерживать клавишу и нажать другую (например: Shift + DEL, DEL, DEL...), не поднимая первую клавишу, чтобы снова запустить событие... Я изменил комментарий @BlakePlumm [скрипка], который добавил комментарий @lu1s на ответ @ParthThakkar.

Кроме того, использование jQuery.on() позволяет прослушивать последовательность клавиш только для определенных элементов. Измените 'body' на 'input.selector' или что-то еще.

var map = [];
var down = [];
$(document).on('keydown','body', function(e) {
    if(!map[e.which]){
        down.push(e.which);
        if(down[0] === 68 && down[1] === 69 && down[2] === 86) {
            console.log('D + E + V');
        } else if(down[0] === 16 && down[1] === 46) {
            console.log('SHIFT + DEL');
        }
        /* more conditions here */
    }
    map[e.which] = true;
}).keyup(function(e) {
    map[e.which] = false;

    /* important for detecting repeat presses of
       last key while holding first key(s)
       (can be shortened. see fiddle) */
    var len = down.length;
    while (len--) {
        if(down[len] === e.which) down.splice(len,1); //removes only the keyup'd key
    }        
    $('.alert').html('');
});

Дополнительные мысли: Если вы только заботитесь о заказе - то есть, первые ключи просто должны быть опущены, если последний нажав клавишу основного события (например, CTRL + SHIFT + TAB, TAB, TAB), добавьте это условие

else if(down.length>2) {
    if($.inArray(68,down)!=-1 && $.inArray(69,down)!=-1 && down[2] === 86) {
        $('.alert').html('A hacky D+E+V was pressed');
    }
}

скрипка с более славными вариантами и живая демонстрация: - http://jsfiddle.net/kstarr/4ftL1p3k/

Ответ 11

https://github.com/JesseBuesking/jquery.hotkeys.extended

Проверьте это. Возможно, вы ищете это.

Мы можем вызвать функцию при многократном нажатии клавиши. например: p + t + k

 $(document).hotkeys('p', 't', 'k', function (){
        //show blurbox
        $('#popup').blurbox({
            blur: 10, animateBlur: true, bgColor: 'rgba(255,255,0,0.2)'
        })bb.show();
    });

Возможно, вы ищете это.