Blog webdeveloperski Patryk yarpo Jar

Obsługa skrótów klawiszowych z poziomu JavaScript

Autor wiadomości Czerwiec 29, 2012

W wielu aplikacjach internetowych (np. GMail) można wykorzystywać znane skróty klawiszowe. W jaki sposób twórcy tych stron zdołali podpiąć się pod wciśnięcie ctrl + S w celu zapisania wersji roboczej listu? Dlaczego nie wyświetla się systemowy dialog zapisu witryny? Na te pytania odpowiem w tym wpisie.

Przechwytywanie zdarzeń klawiatury

Wciśnięcie klawisza na klawiaturze wywołuje kolejno kilka zdarzeń:

  1. keydown
  2. keypress
  3. keyup

W tym wpisie będę korzystał z `keydown'. Więcej nt. obsługi zdarzeń klawiaturowych na stronach dokumentacji mozilli.

Funkcję obsługi zdarzenia przypiszę jako atrybut do znacznika <body />. Pokazane przykłady działają w przeglądarkach. W IE mogą nie działać.

<html>
<head>
<title>Obsługa skrótów klawiszowych</title>
<script type="text/javascript">
    function keyUpHandler(e)
    {
        alert('Wcisnąłeś klawisz!');
    }
</script>
</head>
<body onkeyup="keyUpHandler(event)"></body>
</html>

demo online

Po uruchomieniu powyższego przykładu każde wciśnięcie przycisku na klawiaturze wywoła alert z napisem "Wcisnąłeś klawisz!".

Przechwytywanie zdarzeń klawiatury w Internet Explorerze

Pokazany wyżej przykład działa w przeglądarkach. W IE nie działa. Innym sposobem działającym na pewno w FF i Chromie jest nadpisanie właściwości `onkeyup' obiektu `window':

window.onkeyup = function(e) { alert('działa'); } 

Ten sposób jednak także nie działa w domyślnym programie MS Windows. W Internet Explorerze działa natomiast nadpisanie właściwości `onkeyup' obiektu document:

document.onkeyup = function(e) { alert('działa'); } 

Dlatego w dalszej części wpisu będę używał właśnie tego sposobu.

Problem MSIE z parametrem przekazywanym do handlera

Prócz problematycznego przypisywania funkcji obsługi zdarzeń, występuje także problem z innym przekazywaniem parametru do funkcji obsługi zdarzeń. IE nie przekazuje żadnego parametru. Tworzy natomiast globalny obiekt `event'. Stąd też naszą funkcję należy rozszerzyć o taki kod:

function keyUpHandler(e)
{
    e = e || event;
    alert('Wcisnąłeś klawisz!');
}
document.onkeyup = keyUpHandler;

demo online

W ten sposób udało się załatać (póki co) wszystkie problemy związane z wyrobem giganta z Redmond.

Rozpoznawanie klawiszy Ctrl, Alt, Shift

Większość skrótów klawiszowych jest kombinacją klawiszy ctrl, alt, shift i litery. Jak jednak rozpoznać, że klawisz specjalny został wciśnięty?

Do funkcji obsługi zdarzenia `keyup' przekazywany jest obiekt `KeyboardEvent'. Pośród wielu pól posiada także flagi:

  • altKey
  • ctrlKey
  • shiftKey

Każde z tych pól ma wartość `true'/`false' oznaczającą, czy podczas wciśnięcia innego klawisza ten był również przytrzymany. Dzięki temu łatwo można przechwycić kombinację klawiszy za pomocą prostego warunku:

function keyUpHandler(e)
{
    e = e || event;
    if (e.altKey)
    {
        alert("Z wciśniętym altem");
    }
    if (e.shiftKey)
    {
        alert("Z wciśniętym shiftem");
    }
    if (e.ctrlKey)
    {
        alert("Z wciśniętym control");
    }
}

demo online

Powyższy przykład wyświetli alerty dla kombinacji klawiszowych z ctrl, shift oraz alt. Dla prawego alt uzna, że wciśnięto zarówno ctrl jak i alt.

Warto przeczytać:

Blokowanie domyślnej akcji skrótu

Aby zablokować domyślną akcję wywoływaną na określony skrót należy wykorzystać obsługę zdarzenia `keypress'. Podpięta funkcja obsługi tego zdarzeaia powinna zwracać `false':

document.onkeypress = function()
{
    return false; // zablokuj domyślną akcję skrótu
}

Odczyt wciśniętej litery

Póki co jeszcze nie pokazałem jak odczytać literę. Do odczytu wartości wciśniętej litery służy pole `event.keyCode':

function keyUpHandler(e)
{
    e = e || event;
    alert("kod: " + e.keyCode+ '\nlitera: ' + String.fromCharCode(e.keyCode));
}

demo online

Rozpoznawanie strzałek i klawiszy funkcyjnych

function keyUpHandler(e)
{
    e = e || event;
    alert("kod: " + e.keyCode);
}

demo online

Przydatną informacją mogą być wartości strzałek na klawiaturze (np. do gry napisanej w JavaScript):

  • lewa: 37
  • góra: 38
  • prawa: 39
  • dół: 40

Skróty klawiszowe

Skoro już wiemy jak odczytywać większość wciśniętych klawiszy, czas stworzyć kawałek kod odpowiedzialny za obsługę kliku zdarzeń:

function keyUpHandler(e)
{
    e = e || event;
    var keyCode = e.keyCode,
    letter = (String.fromCharCode(e.keyCode) || '').toLowerCase();

    if (e.altKey &amp;&amp; 'a' === letter || 'ą' === letter)
    {
        alert("Dziwny skrót, ale działa!");
    }
    if (e.shiftKey &amp;&amp; 'b' === letter)
    {
        alert("Wysyłam mail!");
    }
    if (e.ctrlKey &amp;&amp; 's' === letter)
    {
        alert("Zapisuję");
    }
    if (113 === keyCode)
    {
        alert("Wcisnąłeś F2. Ale nie wspieramy tego skrótu");
    }
    return false;
}

demo online

Oczywiście to dopiero początek możliwości pracy z klawiaturą. Można także tworzyć skróty zawierające jednocześnie kilka klawiszów (ctrl, alt, funkcyjne, literę).

Powodzenia 🙂

Komentarze (0) Trackbacks (1)

Leave a comment