KeyboardEvent.keyCode jest przestarzały. Co to oznacza w praktyce?

103

Według MDN zdecydowanie nie powinniśmy korzystać z .keyCodenieruchomości. Jest przestarzały:

https://developer.mozilla.org/en-US/docs/Web/API/KeyboardEvent/keyCode

W szkole W3 ten fakt jest pomniejszony i jest tylko uwaga poboczna, która mówi, że .keyCodejest dostarczana tylko dla kompatybilności i że najnowsza wersja specyfikacji DOM Events zaleca używanie .keyzamiast tego właściwości.

Problem polega na tym, że .keynie jest to obsługiwane przez przeglądarki, więc czego powinniśmy użyć? Czy jest coś, czego mi brakuje?

Jason210
źródło
3
.keyjest obsługiwany we wszystkich głównych programistach
mozilla.org/en-US/docs/Web/API/KeyboardEvent/ ...

Odpowiedzi:

37

Masz trzy sposoby, aby sobie z tym poradzić, ponieważ jest to napisane w udostępnionym linku.

if (event.key !== undefined) {

} else if (event.keyIdentifier !== undefined) {

} else if (event.keyCode !== undefined) {

}

powinieneś się nad nimi zastanowić, to właściwy sposób, jeśli chcesz obsługiwać różne przeglądarki.

Może być łatwiej, jeśli zaimplementujesz coś takiego.

var dispatchForCode = function(event, callback) {
  var code;

  if (event.key !== undefined) {
    code = event.key;
  } else if (event.keyIdentifier !== undefined) {
    code = event.keyIdentifier;
  } else if (event.keyCode !== undefined) {
    code = event.keyCode;
  }

  callback(code);
};
Miguel Lattuada
źródło
15
Czytałem to, ale wydawało się, że jest to dużo dodatkowego kodu z żadnego innego powodu niż MDN powiedział, że coś jest przestarzałe, podczas gdy faktycznie działa dobrze we wszystkich głównych przeglądarkach. Ale jeśli to właściwy sposób, dzięki!
Jason210
3
Wow, spójrz na to. caniuse.com/#search=keyCode (Ta właściwość KeyboardEvent jest obsługiwana we wszystkich przeglądarkach (od IE6 +, Firefox 2+, Chrome 1+ itd. ”mówiących o .keyCode)
Miguel Lattuada
2
Właśnie to jest w tym wszystkim tak irytujące. Wszystkie główne przeglądarki obsługują kod keyCode, ale spróbuj sprawdzić właściwość .key, która jest zalecana i prawie nie używaj jej!
Jason210
4
Tak, zbliżamy się do końca maja 2016 r., A chrome w końcu zaimplementował właściwość KeyboardEvent.key. Safari wraz z każdą przeglądarką mobilną nie dołączyło jeszcze do grupy „16,5% wszystkich użytkowników”. Ponadto, niestety, Microsoft Edge i Gecko kodują całkiem sporo zdarzeń inaczej, na przykład: kluczowe zdarzenie dla strzałki w górę jest kodowane jako „W górę” zamiast „ArrowUp”.
Joshua Dawson
Myślę, że to pomoże ci stackoverflow.com/questions/41465542/…
Maven97
26

Ponadto wszystkie elementy keyCode , które , charCode i keyIdentifier są przestarzałe:
charCodei keyIdentifiersą funkcjami niestandardowymi.
keyIdentifierjest usuwany od Chrome 54, a Opera 41.0
keyCodezwraca 0 po zdarzeniu keypress z normalnymi znakami na FF.

Kluczowa właściwość :

 readonly attribute DOMString key

Przechowuje wartość atrybutu klawisza odpowiadającą naciśniętemu klawiszowi

W chwili pisania tego tekstu keywłaściwość jest obsługiwana przez wszystkie główne przeglądarki od: Firefox 52, Chrome 55, Safari 10.1, Opera 46. Z wyjątkiem Internet Explorera 11, który ma: niestandardowe identyfikatory kluczy i nieprawidłowe działanie z AltGraph. Więcej informacji
Jeśli jest to ważne i / lub zgodność ze starszymi wersjami, możesz użyć wykrywania funkcji, jak w poniższym kodzie:

Zauważ, że keywartość różni się od keyCodelub whichproperties tym, że: zawiera nazwę klucza, a nie jego kod. Jeśli twój program potrzebuje kodów znaków, możesz skorzystać z charCodeAt(). W przypadku pojedynczych drukowalnych znaków, których możesz użyć charCodeAt(), jeśli masz do czynienia z kluczami, których wartości zawierają wiele znaków, takich jak ArrowUp szanse: testujesz klucze specjalne i odpowiednio wykonujesz działania. Więc spróbuj wykonawczych tabelę wartości Keys i odpowiadające im kody charCodeArr["ArrowUp"]=38, charCodeArr["Enter"]=13, charCodeArr[Escape]=27... i tak dalej, proszę spojrzeć na wartości kluczy i ich odpowiednimi kodami

if(e.key!=undefined){
        var characterCode = charCodeArr[e.key] || e.key.charCodeAt(0);
    }else{
        /* As @Leonid suggeted   */
        var characterCode = e.which || e.charCode || e.keyCode || 0;
    }
        /* ... code making use of characterCode variable  */  

Być może zechcesz rozważyć zgodność z poprzednimi wersjami, tj. Używać starszych właściwości, gdy są dostępne, i tylko wtedy, gdy zostaną upuszczone, przełącz się na nowe:

if(e.which || e.charCode || e.keyCode ){
        var characterCode = e.which || e.charCode || e.keyCode;
    }else if (e.key!=undefined){
        var characterCode = charCodeArr[e.key] || e.key.charCodeAt(0);
    }else{
        var characterCode = 0;
    }

Zobacz także: dokumentacjęKeyboardEvent.code nieruchomości i więcej szczegółów w tej odpowiedzi .

user10089632
źródło
Twoje rozwiązanie nie działa w mojej przeglądarce (Windows 10, Chrome 60, klawiatura belgijska). Przede wszystkim charCodeArrfunkcja nie istnieje. Ponadto charCodeAtnie działa dla wszystkich wartości e.key. Na przykład dla klawisza Enter/ Returnwartością e.keywłaściwości jest "Enter", a wykonanie charCodeArrdla tego ciągu zwraca wartość 69(która jest kodem ASCII znaku E).
John Slegers
@JohnSlegers, tak, to była literówka, miałem na myśli tablicę zbudowaną przez użytkownika. Proszę zobaczyć moją zaktualizowaną odpowiedź, aby uzyskać więcej informacji.
user10089632
22

TLDR: Sugeruję, że należy użyć nowego event.keyi event.codewłaściwości zamiast tych starszych. IE i Edge obsługują te właściwości, ale nie obsługują jeszcze nowych nazw kluczy. Dla nich jest mały polyfill, który sprawia, że ​​wyświetlają standardowe nazwy kluczy / kodów:

https://github.com/shvaikalesh/shim-keyboard-event-key


Doszedłem do tego pytania, szukając przyczyny tego samego ostrzeżenia MDN co OP. Po dłuższych poszukiwaniach problem z keyCode:

Problem z używaniem keyCodepolega na tym, że klawiatury inne niż angielskie mogą generować różne wyniki, a nawet klawiatury z różnymi układami mogą dawać niespójne wyniki. Poza tym był przypadek

Jeśli przeczytałeś specyfikację W3C: https://www.w3.org/TR/uievents/#interface-keyboardevent

W praktyce keyCode i charCode są niespójne na różnych platformach, a nawet w tej samej implementacji w różnych systemach operacyjnych lub przy użyciu różnych lokalizacji.

Zagłębia się w opis problemu keyCode: https://www.w3.org/TR/uievents/#legacy-key-attributes

Funkcje te nigdy nie zostały formalnie określone, a obecne implementacje przeglądarek różnią się w znaczący sposób. Duża ilość starszych treści, w tym bibliotek skryptów, które polegają na wykrywaniu klienta użytkownika i odpowiednim działaniu, oznacza, że ​​każda próba sformalizowania tych starszych atrybutów i zdarzeń grozi uszkodzeniem takiej ilości treści, jaką naprawiłaby lub włączyła. Ponadto atrybuty te nie nadają się do użytku międzynarodowego ani nie rozwiązują problemów związanych z dostępnością.

Tak więc, po ustaleniu powodu, dla którego starsza wersja keyCode została zastąpiona, spójrzmy, co musisz zrobić dzisiaj:

  1. Wszystkie nowoczesne przeglądarki obsługują nowe właściwości ( keyi code).
  2. IE i Edge obsługują starszą wersję specyfikacji, która ma inne nazwy dla niektórych kluczy. Możesz użyć do tego podkładki: https://github.com/shvaikalesh/shim-keyboard-event-key (lub skręć własną - i tak jest raczej mała)
  3. Edge naprawił ten błąd w najnowszej wersji (prawdopodobnie zostanie wydana w kwietniu 2018) - https://developer.microsoft.com/en-us/microsoft-edge/platform/issues/8860571/
  4. Zapoznaj się z listą kluczy zdarzeń, których możesz użyć: https://www.w3.org/TR/uievents-key/
kumarharsh
źródło
Według MDN , ani Internet Explorer, ani Edge nie obsługująKeyboardEvent.code. Ponadto wartościkeyicodezależą od przeglądarki. Zarówno kwestie, jakkeyicodeniepraktyczne do wykorzystania w rzeczywistych zastosowaniach.
John Slegers
Jeśli chcę przetestować klawisze strzałek, page up / down, home & end, powinienem użyć keylub code? Zwykle jest to klucz fizyczny, ale może też zależeć od Num Lock i układu ... Jaka jest najlepsza praktyka?
Jake
15

MDN dostarczyło już rozwiązanie:

https://developer.mozilla.org/en-US/docs/Web/API/KeyboardEvent/keyCode

window.addEventListener("keydown", function (event) {
  if (event.defaultPrevented) {
    return; // Should do nothing if the default action has been cancelled
  }

  var handled = false;
  if (event.key !== undefined) {
    // Handle the event with KeyboardEvent.key and set handled true.
  } else if (event.keyIdentifier !== undefined) {
    // Handle the event with KeyboardEvent.keyIdentifier and set handled true.
  } else if (event.keyCode !== undefined) {
    // Handle the event with KeyboardEvent.keyCode and set handled true.
  }

  if (handled) {
    // Suppress "double action" if event handled
    event.preventDefault();
  }
}, true);
Vicky Gonsalves
źródło
3
Niestety keyjest to wartość ciągu charakterystyczna dla przeglądarki, taka jak "Enter"lub, "ArrowUp"i nie ma znormalizowanego sposobu konwersji jej na odpowiedni kod. więc będziesz potrzebować jeszcze więcej standardowego kodu do konwersji między kluczem a kodem.
John Slegers,
8

Na przykład, jeśli chcesz wykryć, czy został kliknięty przycisk „Enter”, czy nie:

Zamiast

event.keyCode === 13

Zrób to jak

event.key === 'Enter'
Thomas Gotwig
źródło