2012-05-18 3 views
36

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

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

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

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

+0

KeyCode может представлять только один ключ. Попробуйте использовать комбинацию клавиш keydown + keyup +, чтобы обнаружить это. – yent

+0

Возможный дубликат [Может ли jQuery .keypress() обнаруживать одновременно несколько ключей?] (Http://stackoverflow.com/questions/4954403/can-jquery-keypress-detect-more-than-onekey -at-the-same-time) –

+0

Рассмотрите возможность изменения принятого ответа на [this] (http://stackoverflow.com/a/35249618/3853934). Он представляет собой более современный и общий подход. –

ответ

59

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

0 Например: Live copy | source

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; 
    } 
}); 

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

+0

мм, как вы уже упоминали, я думаю, что порядок важен для быстрых клавиш .. 'ctrl + v' не то же самое, что' v + ctrl' –

+3

@Vega: ключи модификатора другой чайник рыбы. –

+0

@DreamWave: Нет, обработчик 'keyup' очищает флаги. –

1

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

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...'); 
    } 
});​ 

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

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

Вот working example.


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

+0

Я тестировал это в Chrome, и он не работал с исходными кодами клавиш. Я сталкивался с этим раньше, но я забываю, почему они разные. – FishBasketGordo

0

, если я хорошо понял: пример скрипку, 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())); 
0

Вы должны использовать 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 
         } 
        }); 
+0

Вы * не можете * присвоить значение переменной, которая еще не определена. –

+0

Переменная, не определенная вначале, будет новой переменной в глобальном стеке. Это должно быть просто примером того, как это возможно. Если вы хотите, я могу предоставить JSFiddle, но вопрос уже отмечен как разрешенный ... – kapsi

+0

Это ошибка, а не функция, а также глобальные переменные. –

18

Подобно 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; 
});​ 
+0

скрипка здесь: http://jsfiddle.net/5QYKH/ –

+4

Это действительно хорошо и будет хорошо работать. Если вам нужно сопоставить последовательность ключей, вы можете проверить порядок, нажав на массив: вместо 'down [e.keyCode] = true', скажем' down.push (e.keyCode) 'и вместо этого проверить из этого: 'if (down [68] && down [69] && down [86])', как это: 'if (down [0] === 68 && down [1] === 69 && down [2] === 86) '. – lu1s

+2

Я создал [скрипку] (http://jsfiddle.net/bplumb/B2efC/1/), чтобы добавить комментарий lu1s. –

8

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

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

Код для этого было бы что-то вроде этого:

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

Это не ответ на вопрос, не так ли? –

+0

@ParthThakkar - Из вопроса вы можете получить требование: «заставить его скрытый режим разработчика». Будучи прагматичным, я предложил простую альтернативу достижению того же конечного результата – gplumb

+0

все в порядке ... это может быть способ ... Я просто подумал, что это не ответ на требуемый вопрос, поэтому я просто спросил об этом. ..Но оскорбительно!) –

-1

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

Кроме того, использование jQuery's .on() позволяет прослушивать последовательность клавиш только для определенных элементов. Измените «тело» на «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/

-1

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

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

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

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

может быть, ваш искать для этого.

1

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

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

Я просто написал этот скрипт, и он работает очень хорошо. Он использует 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/

+0

Это не сработает, если пользователь продолжает удерживать клавишу Shift и нажимает S второй раз. Принуждение 'saveArray [0] = false' в событии keydown S (что делает предположение о том, что клавиша Shift было выпущено) является довольно ужасным взломом. С другой стороны, это может быть причина, по которой это сработало для вас. – poshest

+0

Пожалуйста, не используйте * new Array() '. –

0

Немного более современное решение, использует arrow functions и rest parameters:

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>

0

Используйте этот код, что событие вызвано несколькими нажатие клавиш + таймаут после 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); 
}); 
Смежные вопросы