Events - klawisze

Jak powiedzieliśmy sobie w poprzednim rozdziale, różnych eventów jest bardzo dużo. Część z nich używana jest częściej, inne rzadziej. Wśród tej pierwszej grupy z pewnością znajdują się eventy związane z klawiaturą.

keyDown, keyUp, keyPress i input

Najczęściej używanymi eventami w przypadku klawiatury są:

keyDown naciśnięcie klawisza
keyUp puszczenie klawisza
keyPress naciśnięcie i puszczenie klawisza

Zdarzenie keyUp odpalane jest tylko jeden raz - przy puszczeniu klawisza.

Najwięcej problemów zawsze sprawia rozróżnienie, kiedy mamy używać keyDown a kiedy keyPress.

Podstawowa różnica między tymi eventami jest taka, że zdarzenie keyPress odpalane jest cyklicznie tylko kiedy przytrzymujemy klawisz znakowy (litery, cyfry itp).
Oznacza to, że keyPress nie zadziała dla przykładu dla klawiszy Backspace, Delete czy Home.

Drugą różnicą jest nieco inny efekt finałowy. W przypadku zdarzenia keyPress, gdy naciśniemy dwa klawisze równocześnie - np. Shift + A, zdarzenie to zostanie odpalone cyklicznie dla trzymanego klawisza A wraz z ustawioną flagą isShift na true.

W przypadku keyDown, po naciśnięciu klawisza Shift zdarzenie to zacznie być odpalane dla tego klawisza. Gdy następnie naciśniemy A, zdarzenie to będzie dalej odpalane dla klawisza A wraz z włączoną flagą isShift na true.

Dość opisów. Po prostu przetestujmy to w praktyce:

Przetestuj w konsoli

Input

Na szczególną uwagę zasługuje event input. Nie jest on bezpośrednio związany z klawiszami (dlatego nie pobierzemy tutaj wszystkich dodatkowych informacji za pomocą event), ale jest też bardzo często używany w przypadku reakcji na wpisywane rzeczy do formularzy. Event ten jest odpalany w reakcji na zmianę wartości inputa przez użytkownika i może być użyty dla każdego rodzaju pola.

Mamy też event change, ale ten odpalany jest dla inputów dopiero po zawtwierdzeniu zmian (opuszczenie pola input, zmiana optiona w select, kliknięcie w radio).


const form = document.querySelector("#testInput");
[...form.elements].forEach(function(el) {
    el.addEventListener("input", function() {
        console.log(`Wartość pola: ${this.value}`);
    })
})

Który klawisz został naciśnięty

Wartość naciśniętego klawisza jest przechowywana w właściwości key zdarzenia związanego z klawiszami.


document.addEventListener('keyup', function(e) {
    console.log('Klawisz: ' + e.key);
});

Aby wykryć czy dodatkowo został naciśnięty jeden z funkcyjnych klawiszy możemy skorzystać z dodatkowych właściwości:

e.altKey Czy klawisz Alt jest naciśnięty
e.ctrlKey Czy klawisz Ctrl jest naciśnięty
e.shiftKey Czy klawisz Shift jest naciśnięty
e.keyCode Zwraca kod klawisza. Przydatne przy sprawdzaniu zakresów klawiszy - np. klawisz to liczba

const textarea = document.querySelector('#keyTest');

textarea.addEventListener('keyup', function(e) {
    const keys = [];

    if (e.shiftKey) {
        keys.push("shift");
    }
    if (e.altKey) {
        keys.push("alt");
    }
    if (e.ctrlKey) {
        keys.push("ctrl");
    }
    keys.push(e.key);

    console.log("Naciśnięte klawisze: " + keys.join(" + "));

    if (e.keyCode >= 48 && e.keyCode <= 57) {
        console.log('klawisz to cyfra');
    }
});

Możemy to wykorzystać na przykład do stworzenia pola numerycznego. Normalnie pole typu input:number pozwala wpisywać litery z niektórych systemów liczbowych (np. e)

Spróbuj wpisać w poniższe pola typu number literę e:


numerFix.addEventListener('keydown', function(e) {
    if (e.keyCode === 69) {
        e.preventDefault();
        return false;
    }
});

Powyższy przykład to tylko prosta implementacja. Pamiętaj, że wartość pola może się w nim zmienić nie tylko pod wpływem wpisywania. Możemy taką nową wartość wkleić ze schowka, lub zmienić ją za pomocą skryptu (wtedy musimy zareagować na inne eventy - np. paste).

Używany w powyższych przykładach charCode jest uznany za depreaced, czyli nie zaleca się go stosować na rzecz e.code lub e.key. Niestety nie jest to takie proste, ponieważ żadna z tych właściwości nie zwraca kodu klawisza a tylko słowny opis, a dodatkowo e.key nie działa na każdej przeglądarce tak samo. Na ten temat odbyła się już nei jedna dyskusja (1, 2).
Osobiście poczekał bym na ruch jQuery, które na chwilę obecną używa keyCode.

Możliwych zastosować jest cała masa. Niektóre strony za pomocą klawiszy odpalają niektóre funkcjonalności - dla przykładu facebook. W takim przypadku nasze zdarzenie powinniśmy podpiąć pod document


document.addEventListener("keyup", function(e) {
    if (e.key.toUpperCase() === "?") {
        showHelpPopup();
    }
    if (e.key.toUpperCase() === "N") {
        newPost();
    }
})

Wszelkie prawa zastrzeżone. Jeżeli chcesz używać jakiejś części tego kursu, skontaktuj się z autorem. Aha - i ta strona korzysta z ciasteczek.