2012-05-18 10 views
36

È possibile combinare una combinazione di tasti per premere un solo evento?Rileva più chiavi su un singolo evento di pressione tasti in jQuery

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

L'ho provato in Chrome ma l'evento non viene attivato.

Call me pazzo, ma io sto scrivendo un'estensione Chrome e vuole spingere D + E + V chiavi insieme per forzarlo in una modalità sviluppatore nascosta.

+0

Il codice chiave può rappresentare solo una chiave. Prova a utilizzare una combinazione di keydown + keyup + flag per rilevare questo. – yent

+0

possibile duplicato di [Può jQuery .keypress() rilevare più di un tasto allo stesso tempo?] (Http://stackoverflow.com/questions/4954403/can-jquery-keypress-detect-more-than-one-key -at-the-same-time) –

+0

Valuta la possibilità di modificare la risposta accettata a [this] (http://stackoverflow.com/a/35249618/3853934). Presenta un approccio più moderno e generale. –

risposta

59

Se si desidera rilevare che il d, e, e v chiavi erano tutti giù allo stesso tempo, si deve guardare sia keydown e keyup e mantenere una mappa di quelli che sono giù Quando sono tutti a terra, licenzia il tuo evento.

Ad esempio: 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; 
    } 
}); 

Suppongo che non si cura che ordine stanno premuti in (come sarebbe un dolore per premere in modo affidabile) nella misura in cui sono tutti verso il basso allo stesso tempo ad un certo punto.

+0

mm come hai detto, penso che l'ordine sia importante per le scorciatoie da tastiera .. 'ctrl + v' non è uguale a' v + ctrl' –

+3

@Vega: i tasti modificatori sono un diverso bicchiere di pesce. –

+0

@DreamWave: No, il gestore 'keyup' cancella le bandiere. –

1

È necessario acquisire separatamente i tre eventi chiave e attivare l'azione solo dopo il terzo.

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

C'è un certo numero di modi per farlo, naturalmente. Questo esempio non richiede di tenere premuti i tasti contemporaneamente, solo che li digiti in ordine: dev.

Se si è utilizzato questo, si potrebbe desiderare di aumentarlo per cancellare i flag pressed dopo un intervallo di tempo.

Ecco uno working example.


di responsabilità: mi rendo conto la domanda originale, ha detto che le chiavi dovrebbero essere "premuti insieme". Questa è solo un'alternativa in quanto altri rispondenti hanno già fornito soluzioni sufficienti per la compressione dei tasti.

+0

L'ho provato in Chrome e non funzionava con i codici chiave originali. L'ho già incontrato prima, ma ho dimenticato perché sono diversi. – FishBasketGordo

0

se ho ben capito: ad esempio il violino, http://jsfiddle.net/gAtTk/ (guarda la console js)

questo codice vi permetterà di inserire la parola "dev" (e in questo esempio, alla fine della manifestazione keyup viene rimosso)

(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

si dovrebbe usare il keydown e gli eventi KeyUp, di gestire più di un tasto "allo stesso tempo".

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

Non * è possibile * assegnare un valore a una variabile che non è stata ancora definita. –

+0

Una variabile senza essere definita inizialmente sarebbe una nuova variabile sullo stack globale. Questo dovrebbe essere solo un esempio di come ciò sarebbe possibile. Se vuoi, posso fornire un JSFiddle, ma la domanda è già contrassegnata come risolta ... – kapsi

+0

Questo è un bug, non una funzionalità, e anche le variabili globali sono cattive. –

18

Simile a Vega's ...ma più semplice

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

fiddle it qui: http://jsfiddle.net/5QYKH/ –

+4

Questo è veramente buono e funzionerà bene. Se è necessario abbinare una sequenza di tasti, è possibile controllare l'ordine spingendo su una matrice: invece di 'down [e.keyCode] = true', pronunciare' down.push (e.keyCode) 'e convalidare invece di questo: 'if (giù [68] && down [69] && down [86])', come questo: 'if (giù [0] === 68 && down [1] === 69 && down [2] === 86) '. – lu1s

+2

Ho creato un [fiddle] (http://jsfiddle.net/bplumb/B2efC/1/) per integrare il commento di lu1s. –

8

Forse una combinazione di tasti più semplice sarebbe più semplice?

E qualcosa come Shift + Alt + D? (Probabilmente non dovrebbe usare il tasto Control perché la maggior parte dei browser già interpretano Ctrl + D in un modo o nell'altro)

Il codice per questo sarebbe qualcosa di simile:

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

che non è la risposta alla domanda, vero? –

+0

@ParthThakkar - Dalla domanda, puoi ricavare il requisito: "forzarlo in una modalità sviluppatore nascosta". Essendo pragmatico, ho suggerito una semplice alternativa per ottenere lo stesso risultato finale – gplumb

+0

tutto bene ... quella potrebbe essere la strada da percorrere ... ho solo pensato che non era la risposta alla domanda richiesta, quindi l'ho solo chiesto. ..no offesa!) –

-1

Se vi preoccupate per la ordine e anche bisogno di tenere premuto un tasto e toccare un altro (es: Shift + DEL, DEL, DEL ...), senza dover sollevare la prima chiave per far sparare di nuovo l'evento ... Ho modificato @ Il commento [fiddle] di BlakePlumm che ha esteso il commento di @ lu1s sulla risposta di @ ParthThakkar.

Inoltre, utilizzando jQuery's .on() consente di ascoltare la sequenza di tasti solo su determinati elementi. Cambia 'body' in 'input.selector' o qualsiasi altra cosa.

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

pensieri supplementari: Se vi interessa soltanto un po sull'ordine - vale a dire, le prime chiavi solo bisogno di essere giù, fino a quando il tasto-firing evento principale è premuto per ultimo (roba come CTRL + MAIUSC + TAB, TAB, TAB), aggiungi questa condizione:

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

violino con le opzioni più gloriosi e demo live: - http://jsfiddle.net/kstarr/4ftL1p3k/

-1

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

Controllare questo. Potresti cercarlo.

È possibile attivare una funzione premendo più tasti. ad esempio: 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(); 
    }); 

forse la vostra ricerca di questo.

1

Ho provato le tre risposte principali (come di questo post), e nessuno di loro ha funzionato per me. Non hanno ripristinato i tasti.

Se sono necessari 3 tasti, attivare la sceneggiatura, dopo averla attivata una volta, premendo uno dei 3 tasti si attiva di nuovo.

Ho appena scritto questo script e funziona molto bene. Usa Shift + S per sparare, ma puoi facilmente cambiarlo. Si reimposta dopo aver premuto la combinazione.

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

Questo non funzionerà se l'utente continua a tenere premuto il tasto Shift e preme S una seconda volta. Forzare 'saveArray [0] = false' nell'evento keydown di S (che presuppone che il tasto Shift sia stato rilasciato) è un attacco abbastanza orribile. D'altra parte, potrebbe essere solo la ragione per cui questo ha funzionato per te. – poshest

+0

Per favore * non * usare 'new Array()'. –

0

Un po 'più moderna soluzione, sfrutta arrow functions e 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

Usa questo codice per avere un evento innescato da multipla premere i tasti + Timeout dopo 100 ms per prevenire errori di digitazione. In questo esempio: se vengono premuti A, Z, E entro un periodo di tempo di 100 ms, l'evento verrà attivato.

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