Bagaimana cara mendeteksi jika beberapa tombol ditekan sekaligus menggunakan JavaScript?

173

Saya mencoba mengembangkan mesin game JavaScript dan saya menemukan masalah ini:

  • Ketika saya menekan SPACEkarakter melompat.
  • Ketika saya menekan karakter bergerak ke kanan.

Masalahnya adalah ketika saya menekan kanan dan kemudian menekan spasi, karakter melompat dan kemudian berhenti bergerak.

Saya menggunakan keydownfungsi ini untuk menekan tombol. Bagaimana saya dapat memeriksa apakah ada beberapa tombol yang ditekan sekaligus?

XCS
sumber
3
Berikut ini adalah demo dari halaman web yang secara otomatis mencetak daftar semua kunci yang ditekan: stackoverflow.com/a/13651016/975097
Anderson Green

Jawaban:

327

Catatan: keyCode sekarang sudah tidak digunakan lagi.

Deteksi beberapa keystroke mudah jika Anda memahami konsepnya

Cara saya melakukannya adalah seperti ini:

var map = {}; // You could also use an array
onkeydown = onkeyup = function(e){
    e = e || event; // to deal with IE
    map[e.keyCode] = e.type == 'keydown';
    /* insert conditional here */
}

Kode ini sangat sederhana: Karena komputer hanya melewati satu penekanan tombol pada satu waktu, sebuah array dibuat untuk melacak beberapa kunci. Array kemudian dapat digunakan untuk memeriksa satu atau lebih kunci sekaligus.

Hanya untuk menjelaskan, katakanlah Anda menekan Adan B, masing-masing menembakkan keydownperistiwa yang menetapkan map[e.keyCode]nilai e.type == keydown, yang mengevaluasi benar atau salah . Sekarang keduanya map[65]dan map[66]diatur ke true. Ketika Anda melepaskan A, keyupacara menyala, menyebabkan logika yang sama untuk menentukan hasil yang berlawanan untuk map[65](A), yang sekarang salah , tetapi karena map[66](B) masih "turun" (itu belum memicu peristiwa keyup), itu tetap benar .

The maparray, melalui acara, terlihat seperti ini:

// keydown A 
// keydown B
[
    65:true,
    66:true
]
// keyup A
// keydown B
[
    65:false,
    66:true
]

Ada dua hal yang dapat Anda lakukan sekarang:

A) Pencatat Kunci ( contoh ) dapat dibuat sebagai referensi untuk nanti ketika Anda ingin mencari satu atau lebih kode kunci dengan cepat. Dengan asumsi Anda telah mendefinisikan elemen html dan menunjuknya dengan variabel element.

element.innerHTML = '';
var i, l = map.length;
for(i = 0; i < l; i ++){
    if(map[i]){
        element.innerHTML += '<hr>' + i;
    }
}

Catatan: Anda dapat dengan mudah mengambil elemen dengan idatributnya.

<div id="element"></div>

Ini menciptakan elemen html yang dapat dengan mudah direferensikan dalam javascript dengan element

alert(element); // [Object HTMLDivElement]

Anda bahkan tidak perlu menggunakan document.getElementById()atau $()mengambilnya. Tetapi demi kompatibilitas, penggunaan jQuery $()lebih banyak direkomendasikan.

Pastikan tag skrip muncul setelah badan HTML. Kiat pengoptimalan : Sebagian besar situs web dengan nama besar memasang tag skrip setelah tag badan untuk pengoptimalan. Ini karena tag skrip memblokir elemen lebih lanjut dari pemuatan hingga skripnya selesai diunduh. Menempatkannya di depan konten memungkinkan konten untuk memuat sebelumnya.

B (di mana minat Anda terletak) Anda dapat memeriksa satu atau lebih kunci pada saat /*insert conditional here*/itu, ambil contoh ini:

if(map[17] && map[16] && map[65]){ // CTRL+SHIFT+A
    alert('Control Shift A');
}else if(map[17] && map[16] && map[66]){ // CTRL+SHIFT+B
    alert('Control Shift B');
}else if(map[17] && map[16] && map[67]){ // CTRL+SHIFT+C
    alert('Control Shift C');
}

Sunting : Itu bukan cuplikan yang paling mudah dibaca. Keterbacaan penting, sehingga Anda dapat mencoba sesuatu seperti ini untuk memudahkan mata:

function test_key(selkey){
    var alias = {
        "ctrl":  17,
        "shift": 16,
        "A":     65,
        /* ... */
    };

    return key[selkey] || key[alias[selkey]];
}

function test_keys(){
    var keylist = arguments;

    for(var i = 0; i < keylist.length; i++)
        if(!test_key(keylist[i]))
            return false;

    return true;
}

Pemakaian:

test_keys(13, 16, 65)
test_keys('ctrl', 'shift', 'A')
test_key(65)
test_key('A')

Ini lebih baik?

if(test_keys('ctrl', 'shift')){
    if(test_key('A')){
        alert('Control Shift A');
    } else if(test_key('B')){
        alert('Control Shift B');
    } else if(test_key('C')){
        alert('Control Shift C');
    }
}

(akhir suntingan)


Contoh ini memeriksa CtrlShiftA, CtrlShiftBdanCtrlShiftC

Ini sesederhana itu :)

Catatan

Melacak Kode Kunci

Sebagai aturan umum, adalah praktik yang baik untuk mendokumentasikan kode, terutama hal-hal seperti Kode kunci (seperti // CTRL+ENTER) sehingga Anda dapat mengingat apa itu.

Anda juga harus meletakkan kode kunci dalam urutan yang sama dengan dokumentasi ( CTRL+ENTER => map[17] && map[13], BUKAN map[13] && map[17]). Dengan cara ini Anda tidak akan pernah bingung ketika Anda perlu kembali dan mengedit kode.

Gotcha dengan rantai if-else

Jika memeriksa kombo dengan jumlah berbeda (seperti CtrlShiftAltEnterdan CtrlEnter), masukkan kombo yang lebih kecil setelah kombo yang lebih besar, atau kombo yang lebih kecil akan mengesampingkan kombo yang lebih besar jika mereka cukup mirip. Contoh:

// Correct:
if(map[17] && map[16] && map[13]){ // CTRL+SHIFT+ENTER
    alert('Whoa, mr. power user');
}else if(map[17] && map[13]){ // CTRL+ENTER
    alert('You found me');
}else if(map[13]){ // ENTER
    alert('You pressed Enter. You win the prize!')
}

// Incorrect:
if(map[17] && map[13]){ // CTRL+ENTER
    alert('You found me');
}else if(map[17] && map[16] && map[13]){ // CTRL+SHIFT+ENTER
    alert('Whoa, mr. power user');
}else if(map[13]){ // ENTER
    alert('You pressed Enter. You win the prize!');
}
// What will go wrong: When trying to do CTRL+SHIFT+ENTER, it will
// detect CTRL+ENTER first, and override CTRL+SHIFT+ENTER.
// Removing the else's is not a proper solution, either
// as it will cause it to alert BOTH "Mr. Power user" AND "You Found Me"

Gotcha: "Kombo kunci ini tetap aktif meskipun saya tidak menekan tombol"

Saat berurusan dengan peringatan atau apa pun yang mengambil fokus dari jendela utama, Anda mungkin ingin menyertakan map = []untuk mengatur ulang array setelah kondisi selesai. Ini karena beberapa hal, seperti alert(), mengalihkan fokus dari jendela utama dan menyebabkan acara 'keyup' tidak terpicu. Sebagai contoh:

if(map[17] && map[13]){ // CTRL+ENTER
    alert('Oh noes, a bug!');
}
// When you Press any key after executing this, it will alert again, even though you 
// are clearly NOT pressing CTRL+ENTER
// The fix would look like this:

if(map[17] && map[13]){ // CTRL+ENTER
    alert('Take that, bug!');
    map = {};
}
// The bug no longer happens since the array is cleared

Gotcha: Default Peramban

Inilah hal yang menjengkelkan yang saya temukan, termasuk solusinya:

Masalah: Karena browser biasanya memiliki tindakan default pada kombo kunci (seperti CtrlDmengaktifkan jendela bookmark, atau CtrlShiftCmengaktifkan skynote di maxthon), Anda mungkin juga ingin menambahkan return falsesetelah map = [], sehingga pengguna situs Anda tidak akan frustrasi ketika "Duplicate File" fungsi, sedang memakai CtrlD, bookmark halaman sebagai gantinya.

if(map[17] && map[68]){ // CTRL+D
    alert('The bookmark window didn\'t pop up!');
    map = {};
    return false;
}

Tanpa return false, jendela Bookmark akan muncul, yang membuat pengguna kecewa.

Pernyataan pengembalian (baru)

Oke, jadi Anda tidak selalu ingin keluar dari fungsi pada saat itu. Itu sebabnya event.preventDefault()fungsinya ada di sana. Apa yang dilakukannya adalah menetapkan bendera internal yang memberi tahu juru bahasa untuk tidak mengizinkan browser untuk menjalankan tindakan standarnya. Setelah itu, eksekusi fungsi berlanjut (padahal returnakan segera keluar fungsi).

Pahami perbedaan ini sebelum Anda memutuskan apakah akan menggunakan return falseataue.preventDefault()

event.keyCode sudah ditinggalkan

Pengguna SeanVieira menunjukkan dalam komentar yang event.keyCodesudah usang.

Di sana, ia memberikan alternatif yang sangat baik:, event.keyyang mengembalikan representasi string dari tombol yang ditekan, seperti "a"untuk A, atau "Shift"untukShift .

Saya pergi ke depan dan memasak alat untuk memeriksa string tersebut.

element.onevent vs. element.addEventListener

Penangan yang terdaftar addEventListenerdapat ditumpuk, dan dipanggil dalam urutan pendaftaran, sementara pengaturan .oneventlangsung agak agresif dan menimpa apa pun yang sebelumnya Anda miliki.

document.body.onkeydown = function(ev){
    // do some stuff
    ev.preventDefault(); // cancels default actions
    return false; // cancels this function as well as default actions
}

document.body.addEventListener("keydown", function(ev){
    // do some stuff
    ev.preventDefault() // cancels default actions
    return false; // cancels this function only
});

The .oneventproperti tampaknya menimpa segala sesuatu dan perilaku ev.preventDefault()danreturn false; bisa agak tak terduga.

Dalam kedua kasus, penangan terdaftar melalui addEventlistener tampaknya lebih mudah untuk menulis dan mempertimbangkannya.

Ada juga attachEvent("onevent", callback)dari implementasi non-standar Internet Explorer, tetapi ini sudah usang dan bahkan tidak berkaitan dengan JavaScript (itu berkaitan dengan bahasa esoterik yang disebut JScript ). Akan menjadi kepentingan terbaik Anda untuk menghindari kode polyglot sebanyak mungkin.

Kelas pembantu

Untuk mengatasi kebingungan / keluhan, saya telah menulis "kelas" yang melakukan abstraksi ini ( tautan pastebin ):

function Input(el){
    var parent = el,
        map = {},
        intervals = {};
    
    function ev_kdown(ev)
    {
        map[ev.key] = true;
        ev.preventDefault();
        return;
    }
    
    function ev_kup(ev)
    {
        map[ev.key] = false;
        ev.preventDefault();
        return;
    }
    
    function key_down(key)
    {
        return map[key];
    }

    function keys_down_array(array)
    {
        for(var i = 0; i < array.length; i++)
            if(!key_down(array[i]))
                return false;

        return true;
    }
    
    function keys_down_arguments()
    {
        return keys_down_array(Array.from(arguments));
    }
    
    function clear()
    {
        map = {};
    }
    
    function watch_loop(keylist, callback)
    {
        return function(){
            if(keys_down_array(keylist))
                callback();
        }
    }

    function watch(name, callback)
    {
        var keylist = Array.from(arguments).splice(2);

        intervals[name] = setInterval(watch_loop(keylist, callback), 1000/24);
    }

    function unwatch(name)
    {
        clearInterval(intervals[name]);
        delete intervals[name];
    }

    function detach()
    {
        parent.removeEventListener("keydown", ev_kdown);
        parent.removeEventListener("keyup", ev_kup);
    }
    
    function attach()
    {
        parent.addEventListener("keydown", ev_kdown);
        parent.addEventListener("keyup", ev_kup);
    }
    
    function Input()
    {
        attach();

        return {
            key_down: key_down,
            keys_down: keys_down_arguments,
            watch: watch,
            unwatch: unwatch,
            clear: clear,
            detach: detach
        };
    }
    
    return Input();
}

Kelas ini tidak melakukan segalanya dan tidak akan menangani setiap kasus penggunaan yang mungkin. Saya bukan orang perpustakaan. Tetapi untuk penggunaan interaktif umum itu harus baik-baik saja.

Untuk menggunakan kelas ini, buat instance dan arahkan ke elemen yang ingin Anda kaitkan dengan input keyboard:

var input_txt = Input(document.getElementById("txt"));

input_txt.watch("print_5", function(){
    txt.value += "FIVE ";
}, "Control", "5");

Apa yang akan dilakukan adalah melampirkan pendengar input baru ke elemen dengan #txt(mari kita asumsikan itu adalah textarea), dan menetapkan titik pantauan untuk kombo kunci Ctrl+5. Saat keduanya Ctrldan 5sedang turun, fungsi panggilan balik yang Anda berikan (dalam hal ini, fungsi yang menambah "FIVE "textarea) akan dipanggil. Callback dikaitkan dengan nama print_5, jadi untuk menghapusnya, Anda cukup menggunakan:

input_txt.unwatch("print_5");

Untuk melepaskan input_txtdari txtelemen:

input_txt.detach();

Dengan cara ini, pengumpulan sampah dapat mengambil objek ( input_txt), harus dibuang, dan Anda tidak akan memiliki pendengar acara zombie yang tersisa.

Untuk ketelitian, berikut adalah referensi cepat ke API kelas, disajikan dalam gaya C / Java sehingga Anda tahu apa yang mereka kembalikan dan argumen apa yang mereka harapkan.

Boolean  key_down (String key);

Mengembalikan truejika keydown, false jika tidak.

Boolean  keys_down (String key1, String key2, ...);

Kembali truejika semua kunci key1 .. keyNturun, salah jika sebaliknya.

void     watch (String name, Function callback, String key1, String key2, ...);

Menciptakan "titik pandang" sehingga menekan semua keyNakan memicu panggilan balik

void     unwatch (String name);

Menghapus kata titik pantauan melalui namanya

void     clear (void);

Usap cache "kunci ke bawah". Setara dengan di map = {}atas

void     detach (void);

Lepaskan ev_kdowndan ev_kuppendengar dari elemen induk, sehingga memungkinkan untuk menyingkirkan instance secara aman

Pembaruan 2017-12-02 Menanggapi permintaan untuk menerbitkan ini ke github, saya telah membuat inti .

Pembaruan 2018-07-21 Saya sudah bermain dengan pemrograman gaya deklaratif untuk sementara waktu, dan cara ini sekarang menjadi favorit pribadi saya: biola , pastebin

Secara umum, ini akan bekerja dengan case yang Anda inginkan secara realistis (ctrl, alt, shift), tetapi jika Anda perlu menekan, katakanlah, a+wpada saat yang sama, itu tidak akan terlalu sulit untuk "menggabungkan" pendekatan menjadi sebuah pencarian multi-kunci.


Saya harap jawaban yang dijelaskan di blog ini sangat membantu :)

Braden Best
sumber
Saya baru saja membuat pembaruan besar untuk jawaban ini! Contoh keylogger lebih masuk akal, saya memperbarui format sehingga bagian "catatan" akan lebih mudah dibaca, dan saya menambahkan catatan baru tentang return falsevspreventDefault()
Braden Best
Bagaimana ketika Anda menekan / menahan kunci dengan dokumen dalam fokus, lalu Anda mengklik kotak URL, lalu Anda melepaskan kunci tersebut. keyup tidak pernah diaktifkan, namun kuncinya naik, menyebabkan daftar salah. Begitu juga sebaliknya: tekan tombol / tahan di kotak URL, keydown tidak pernah dipecat, kemudian fokus pada dokumen dan status keydown tidak ada dalam daftar. Pada dasarnya setiap kali dokumen mendapatkan kembali fokus Anda tidak pernah bisa memastikan status kunci.
user3015682
3
NB: keyCodesudah usang - jika Anda beralih ke keymaka Anda mendapatkan representasi karakter sebenarnya dari tombol yang bisa bagus.
Sean Vieira
1
@SeanVieira Kemudian lagi, Anda dapat melakukan beberapa hal aneh di C juga. Misalnya, apakah Anda tahu bahwa myString[5]itu sama dengan 5[myString], dan itu bahkan tidak akan memberi Anda peringatan kompilasi (bahkan dengan -Wall -pedantic)? Itu karena pointer[offset]notasi mengambil pointer, menambahkan offset, dan kemudian mereferensikan hasilnya, menjadikannya myString[5]sama dengan *(myString + 5).
Braden Best
1
@inorganik yang Anda maksudkan dengan kelas pembantu? Bisakah inti digunakan seperti repo? Akan membosankan untuk membuat repo keseluruhan untuk potongan kode kecil. Tentu, saya akan membuat intisari. Saya akan menembak untuk malam ini. Midnight mountain Time -ish
Braden Best
30

Anda harus menggunakan acara keydown untuk melacak tombol yang ditekan, dan Anda harus menggunakan acara keyup untuk melacak kapan tombol dilepaskan.

Lihat contoh ini: http://jsfiddle.net/vor0nwe/mkHsU/

(Pembaruan: Saya mereproduksi kode di sini, dalam kasus jsfiddle.net menebus :) HTML:

<ul id="log">
    <li>List of keys:</li>
</ul>

... dan Javascript (menggunakan jQuery):

var log = $('#log')[0],
    pressedKeys = [];

$(document.body).keydown(function (evt) {
    var li = pressedKeys[evt.keyCode];
    if (!li) {
        li = log.appendChild(document.createElement('li'));
        pressedKeys[evt.keyCode] = li;
    }
    $(li).text('Down: ' + evt.keyCode);
    $(li).removeClass('key-up');
});

$(document.body).keyup(function (evt) {
    var li = pressedKeys[evt.keyCode];
    if (!li) {
       li = log.appendChild(document.createElement('li'));
    }
    $(li).text('Up: ' + evt.keyCode);
    $(li).addClass('key-up');
});

Dalam contoh itu, saya menggunakan array untuk melacak tombol mana yang sedang ditekan. Dalam aplikasi nyata, Anda mungkin ingindelete setiap elemen begitu kunci terkait mereka telah dirilis.

Perhatikan bahwa walaupun saya telah menggunakan jQuery untuk membuat hal-hal mudah bagi diri saya dalam contoh ini, konsep ini berfungsi dengan baik ketika bekerja di Javascript 'mentah'.

Martijn
sumber
Tapi seperti yang saya pikir ada bug. Jika Anda terus menekan satu tombol kemudian beralih ke tab lain (atau fokus longgar) sambil tetap menahan tombol ketika Anda memfokuskan kembali pada scrit itu akan menunjukkan bahwa tombol ditekan bahkan jika itu tidak. : D
XCS
3
@ Christy: maka Anda juga bisa menambahkan onblurevent handler, yang menghapus semua tombol yang ditekan dari array. Setelah kehilangan fokus, masuk akal jika harus menekan semua tombol lagi. Sayangnya, tidak ada JS yang setara dengan GetKeyboardState.
Martijn
1
Mengalami masalah dengan Tempel pada Mac (Chrome). Berhasil mendapatkan keydown 91 (perintah), keydown 86 (v), tetapi kemudian hanya keyup 91, meninggalkan 86 ke bawah. Daftar kunci: Atas: 91, Bawah: 86. Ini sepertinya hanya terjadi ketika melepaskan tombol perintah kedua - jika saya melepaskannya terlebih dahulu, daftarkan dengan benar keyup pada keduanya.
James Alday
2
Tampaknya ketika Anda menekan tiga tombol atau lebih sekaligus, itu berhenti mendeteksi tombol lagi sampai Anda mengangkat satu. (Diuji dengan Firefox 22)
Qvcool
1
@JamesAlday Masalah yang sama. Tampaknya itu hanya memengaruhi kunci Meta (OS) pada Mac. Lihat edisi # 3 di sini: bitspushedaround.com/...
Don McCurdy
20
document.onkeydown = keydown; 

function keydown (evt) { 

    if (!evt) evt = event; 

    if (evt.ctrlKey && evt.altKey && evt.keyCode === 115) {

        alert("CTRL+ALT+F4"); 

    } else if (evt.shiftKey && evt.keyCode === 9) { 

        alert("Shift+TAB");

    } 

}
Eduardo La Hoz Miranda
sumber
1
Ini semua yang saya inginkan, jawaban terbaik
Randall Coding
7

Saya menggunakan cara ini (harus memeriksa dimanapun Shift + Ctrl ditekan):

// create some object to save all pressed keys
var keys = {
    shift: false,
    ctrl: false
};

$(document.body).keydown(function(event) {
// save status of the button 'pressed' == 'true'
    if (event.keyCode == 16) {
        keys["shift"] = true;
    } else if (event.keyCode == 17) {
        keys["ctrl"] = true;
    }
    if (keys["shift"] && keys["ctrl"]) {
        $("#convert").trigger("click"); // or do anything else
    }
});

$(document.body).keyup(function(event) {
    // reset status of the button 'released' == 'false'
    if (event.keyCode == 16) {
        keys["shift"] = false;
    } else if (event.keyCode == 17) {
        keys["ctrl"] = false;
    }
});
Himpunan
sumber
5

untuk yang membutuhkan kode contoh lengkap. Kanan + Kiri ditambahkan

var keyPressed = {};
document.addEventListener('keydown', function(e) {

   keyPressed[e.key + e.location] = true;

    if(keyPressed.Shift1 == true && keyPressed.Control1 == true){
        // Left shift+CONTROL pressed!
        keyPressed = {}; // reset key map
    }
    if(keyPressed.Shift2 == true && keyPressed.Control2 == true){
        // Right shift+CONTROL pressed!
        keyPressed = {};
    }

}, false);

document.addEventListener('keyup', function(e) {
   keyPressed[e.key + e.location] = false;

   keyPressed = {};
}, false);
Reza Ramezanpour
sumber
3

Buat keydown memanggil beberapa fungsi, dengan masing-masing fungsi memeriksa kunci tertentu dan merespons dengan tepat.

document.keydown = function (key) {

    checkKey("x");
    checkKey("y");
};
AnonymousGuest
sumber
2

Saya akan mencoba menambahkan keypress Eventhandler keydown. Misalnya:

window.onkeydown = function() {
    // evaluate key and call respective handler
    window.onkeypress = function() {
       // evaluate key and call respective handler
    }
}

window.onkeyup = function() {
    window.onkeypress = void(0) ;
}

Ini hanya dimaksudkan untuk menggambarkan suatu pola; Saya tidak akan masuk ke detail di sini (terutama tidak ke level2 + Eventregistrasi khusus browser ).

Harap kirim kembali apakah ini membantu atau tidak.

FK82
sumber
1
Ini tidak akan bekerja: menekan tombol tidak memicu pada banyak kunci yang keydown dan keyup lakukan pemicu. Juga, tidak semua browser berulang kali memicu peristiwa keydown.
Martijn
Quirksmode mengatakan kesalahan Anda: quirksmode.org/dom/events/keys.html . Tapi saya tidak akan berdebat karena saya tidak menguji proposal saya.
FK82
Dikutip dari halaman itu: "Ketika pengguna menekan tombol-tombol khusus seperti tombol panah, browser TIDAK boleh mem-boot peristiwa penekanan tombol" . Adapun pengulangan, itu daftar Opera dan Konqueror sebagai tidak melakukan itu dengan benar.
Martijn
2

Jika salah satu tombol yang ditekan adalah Alt / Crtl / Shift Anda dapat menggunakan metode ini:

document.body.addEventListener('keydown', keysDown(actions) );

function actions() {
   // do stuff here
}

// simultaneous pressing Alt + R
function keysDown (cb) {
  return function (zEvent) {
    if (zEvent.altKey &&  zEvent.code === "KeyR" ) {
      return cb()
    }
  }
}
Michael Lester
sumber
2
    $(document).ready(function () {
        // using ascii 17 for ctrl, 18 for alt and 83 for "S"
        // ctr+alt+S
        var map = { 17: false, 18: false, 83: false };
        $(document).keyup(function (e) {
            if (e.keyCode in map) {
                map[e.keyCode] = true;
                if (map[17] && map[18] && map[83]) {
                    // Write your own code here, what  you want to do
                    map[17] = false;
                    map[18] = false;
                    map[83] = false;
                }
            }
            else {
                // if u press any other key apart from that "map" will reset.
                map[17] = false;
                map[18] = false;
                map[83] = false;
            }
        });

    });
Prosun Chakraborty
sumber
Terima kasih atas kontribusi Anda. tolong jangan hanya memposting kode, tambahkan beberapa penjelasan.
Tim Rutter
2

Ini bukan metode universal, tetapi bermanfaat dalam beberapa kasus. Ini berguna untuk kombinasi seperti CTRL+ somethingatau Shift+ somethingatau CTRL+ Shift+ something, dll.

Contoh: Ketika Anda ingin mencetak halaman menggunakan CTRL+ P, penekanan tombol pertama selalu CTRLdiikuti oleh P. Sama dengan CTRL+ S, CTRL+ Udan kombinasi lainnya.

document.addEventListener('keydown',function(e){
      
    //SHIFT + something
    if(e.shiftKey){
        switch(e.code){

            case 'KeyS':
                console.log('Shift + S');
                break;

        }
    }

    //CTRL + SHIFT + something
    if(e.ctrlKey && e.shiftKey){
        switch(e.code){

            case 'KeyS':
                console.log('CTRL + Shift + S');
                break;

        }
    }

});

Jakub Muda
sumber
1
case 65: //A
jp = 1;
setTimeout("jp = 0;", 100);

if(pj > 0) {
ABFunction();
pj = 0;
}
break;

case 66: //B
pj = 1;
setTimeout("pj = 0;", 100);

if(jp > 0) {
ABFunction();
jp = 0;
}
break;

Bukan cara terbaik, saya tahu.

Anonim
sumber
-1
Easiest, and most Effective Method

//check key press
    function loop(){
        //>>key<< can be any string representing a letter eg: "a", "b", "ctrl",
        if(map[*key*]==true){
         //do something
        }
        //multiple keys
        if(map["x"]==true&&map["ctrl"]==true){
         console.log("x, and ctrl are being held down together")
        }
    }

//>>>variable which will hold all key information<<
    var map={}

//Key Event Listeners
    window.addEventListener("keydown", btnd, true);
    window.addEventListener("keyup", btnu, true);

    //Handle button down
      function btnd(e) {
      map[e.key] = true;
      }

    //Handle Button up
      function btnu(e) {
      map[e.key] = false;
      }

//>>>If you want to see the state of every Key on the Keybaord<<<
    setInterval(() => {
                for (var x in map) {
                    log += "|" + x + "=" + map[x];
                }
                console.log(log);
                log = "";
            }, 300);
penyihir terbang
sumber