Отримайте значення символу від KeyCode в JavaScript ... потім обріжте


152

Ось що я маю зараз:

$("input").bind("keydown",function(e){
    var value = this.value + String.fromCharCode(e.keyCode);
}

Якщо e.keyCodeне може бути ASCII символів ( Alt, backspace, del, arrows., І т.д.) ... Я б зараз потрібен trimці значення від valueяких - то чином (переважно програмно - ні з таблицями пошуку).

Я використовую jQuery.

Я повинен використовувати keydownподію. keyPressне включається для певного клавіша мені потрібен захоплення ( Esc, del, backspaceі т.д.).

Я не можу використовувати, setTimeoutщоб отримати значення вводу. setTimeout(function(){},0)занадто повільно.


11
Ви повинні використовувати keydownдля зйомки символьних кодів? Ви їдете на пекло їзди: quirksmode.org/js/keys.html (підказка: використовуйте keypress!! )
Crescent Fresh

1
Випадок характеру не має значення. І мені потрібно захопити вгору, вниз, вліво, вправо, esc, del, backspace як мінімум для FF та IE; тож натискання клавіш не підлягає. Дякую за підказку. :-)
Девід Мердок

У відповідь на цю проблему я щойно написав плагін jQuery: github.com/bpeacock/key-to-charCode Це трохи знищено і брудно, і його можна краще інтегрувати в jQuery, але це початок.
Брайан Павич

1
Для всіх, хто прийшов сюди, намагаючись вирішити проблему KeyCode, але дійсно просто хоче побачити, яку клавішу натиснули, ознайомтеся з цією відповіддю . TLDR:document.onkeydown = function(e){ console.log('Key: ' + e.key); }
користувач1717828

Відповіді:


164

Можливо, я неправильно не зрозумів питання, але чи не можете ви використовувати, keyupякщо ви хочете взяти обидва входи?

$("input").bind("keyup",function(e){
    var value = this.value + String.fromCharCode(e.keyCode);
});

10
Це не працює з іншими місцевостями, які знаходяться за межами діапазону ASCII (наприклад, латинська-1, наприклад, німецька, французька, італійська та іспанська, якщо потрібно знати). Очевидно також виходить з ладу для недрукуваних ключів.
Флоріан Бьош

9
Це також не вдається при використанні цифр на цифровій панелі, напр .keyCode не є кодом ASCII (або навіть UTF-x).
Том Чівертон

2
Погана відповідь, вона навіть не працює з основними символами. Наприклад, крапкою з комою з комою є 186, запустіть на ній String.fromCharCode (), і ви отримаєте сміття. Проблема полягає в тому, що keyCode не відповідає ASCII для всіх символів. Символ ASCII для крапки з комою - 59. Це ж питання стосується кожного спеціального символу, keyCode НЕ повертає правильний код для String.fromCharCode ().
Олександр Цепков

193

На мій досвід String.fromCharCode(e.keyCode)ненадійний. String.fromCharCodeочікує, що аргументи unicode - як аргумент; e.keyCodeповертає ключові коди javascript. Клавіші Javascript і шаблони Unicode - це не одне і те ж! Зокрема, клавіші цифрової клавіатури повертають різні keycodeвід звичайних цифрових клавіш (оскільки вони різні клавіші), тоді як однакові keycodeповертаються як для букв, так upperі для lowercaseлітер (ви натискали одну і ту ж клавішу в обох випадках), незважаючи на те, що вони відрізняються charcodes.

Наприклад, звичайний цифровий клавіш 1 генерує подію з keycode49, тоді як клавіша цифрової клавіатури 1 (з Numlockувімкненою) генерує keycode97. За допомогою String.fromCharCodeми отримуємо наступне:

String.fromCharCode(49) returns "1"
String.fromCharCode(97) returns "a"

String.fromCharCodeочікує код Unicode, а не JavaScript. Ключ aгенерує подію з keycode65, незалежно від випадку символу, який він би генерував (також існує модифікатор, якщо Shiftв події натискається клавіша тощо). Символ aмає унікод charcode61, тоді як символ Aмає charcode41 (згідно, наприклад, http://www.utf8-chartable.de/ ). Однак це hexзначення, перетворення в десятковий дає нам charcode65 для "A" і 97 для "a". [1] Це відповідає тому, що ми отримуємо String.fromCharCodeдля цих значень.

Моя власна вимога обмежувалася обробкою номерів та звичайних букв (прийняттям або відхиленням залежно від позиції в рядку) та пропусканням керуючих символів ( F-кільки, -що Ctrl). Таким чином, я можу перевірити наявність контрольних символів, якщо це не контрольний символ, я перевіряю діапазон і лише тоді мені потрібно отримати фактичний символ. Враховуючи те, що я не переживаю за випадок (я все-таки змінюю всі літери на великі регістри) і вже обмежив діапазон клавішних кодів, мені залишається турбуватися лише про клавіші цифрової клавіатури. Для цього достатньо:

String.fromCharCode((96 <= key && key <= 105)? key-48 : key)

Більш загально, функція надійного повернення символу з значень charcodeбула б чудовою (можливо, як плагін jQuery), але я не встигаю зараз це написати. Вибачте.

Я також зазначив e.which(якщо ви використовуєте jQuery), який нормалізується, e.keyCodeі e.charCodeвам не потрібно турбуватися про те, яку клавішу натискали. Проблема з поєднанням її з String.fromCharCodeзалишками.

[1] Я деякий час був розгублений -. всі документи кажуть, що String.fromCharCodeочікує, що Unicode очікує charcode, хоча на практиці це здавалося, що він працює для ASCII-кодів, але це, на мою думку, пояснюється необхідністю перетворення в десяткові з шестигранних, в поєднанні з тим, що діаграми ASCII і однокольорові десяткові коди перекриваються для звичайних латинські літери.


2
Цей коментар майже вирішив усі мої проблеми. Мені дивовижно, що jQuery не реалізував "fromKeyCode", еквівалентному JavaScript "String.fromCharCode"
Chris J

27
Здається, що це робить подія KeyPress. Дивіться stackoverflow.com/a/9350415/209568 . З Документів jQuery "Зауважте, що клавіша та клавіша надають код, який вказує, яка клавіша натиснута, а натискання клавіші вказує, який символ був введений. Наприклад, мале" a "буде повідомлятися як 65 за допомогою клавіш і клавіатури, а як 97 за допомогою натискання клавіші . У всіх подіях великі регістри "А" повідомляються як 65. Через цю різницю кращий вибір під час лову спеціальних натискань клавіш, таких як клавіші зі стрілками, .keydown () або .keyup (). "
Адам

Це найбільш неприємно для тих із нас, хто пристрастився до клавіатури.
Ісаак Болінгер

Примітка до цього останнього біта про ASCII та Unicode. У Unicode всі 128 символів ASCII в одному місці. Це було навмисно, так що будь-який файл, спочатку закодований як ASCII, може маскуватися під Unicode (і бути перетвореним у нього) без необхідності роботи. Однак розширені символи ASCII не в тому самому місці, тому якщо ви використовували цих символів, вам не пощастило.
DanielM

1
Сенс keyCodeполягає в тому, щоб знати, яку клавішу натискали, а не знати, який символ використовувати. Наприклад, "U" на клавіатурі Dvorak має той самий код клавіш, що і "F" на клавіатурі QWERTY або "ㄹ" на корейській клавіатурі і т. Д. Сенс не в тому, щоб перетворити його в символ, це там, щоб ви могли легко зіставляйте речі на положення клавіатури.
Вінсент Макнабб

77

Зчитувані імена ключів, індексовані кодом ключа

Є відносно невелике число ключових кодів , так що я просто перераховані всі відповідні значення в статичному масиві , так що я міг би просто перетворити число 65в AвикористанніkeyboardMap[65]

Не всі ключові коди зіставляються з символом для друку, тому повертається якась інша ідентифікована рядок.

Можливо, вам доведеться змінити масив відповідно до ваших потреб, і ви можете просто повернути порожні рядки для всіх символів, які ви не хочете перекладати. Наступний масив дозволяє швидко і надійно визначити, яку клавішу натискали в будь-якому середовищі. Насолоджуйтесь!

// names of known key codes (0-255)

var keyboardMap = [
  "", // [0]
  "", // [1]
  "", // [2]
  "CANCEL", // [3]
  "", // [4]
  "", // [5]
  "HELP", // [6]
  "", // [7]
  "BACK_SPACE", // [8]
  "TAB", // [9]
  "", // [10]
  "", // [11]
  "CLEAR", // [12]
  "ENTER", // [13]
  "ENTER_SPECIAL", // [14]
  "", // [15]
  "SHIFT", // [16]
  "CONTROL", // [17]
  "ALT", // [18]
  "PAUSE", // [19]
  "CAPS_LOCK", // [20]
  "KANA", // [21]
  "EISU", // [22]
  "JUNJA", // [23]
  "FINAL", // [24]
  "HANJA", // [25]
  "", // [26]
  "ESCAPE", // [27]
  "CONVERT", // [28]
  "NONCONVERT", // [29]
  "ACCEPT", // [30]
  "MODECHANGE", // [31]
  "SPACE", // [32]
  "PAGE_UP", // [33]
  "PAGE_DOWN", // [34]
  "END", // [35]
  "HOME", // [36]
  "LEFT", // [37]
  "UP", // [38]
  "RIGHT", // [39]
  "DOWN", // [40]
  "SELECT", // [41]
  "PRINT", // [42]
  "EXECUTE", // [43]
  "PRINTSCREEN", // [44]
  "INSERT", // [45]
  "DELETE", // [46]
  "", // [47]
  "0", // [48]
  "1", // [49]
  "2", // [50]
  "3", // [51]
  "4", // [52]
  "5", // [53]
  "6", // [54]
  "7", // [55]
  "8", // [56]
  "9", // [57]
  "COLON", // [58]
  "SEMICOLON", // [59]
  "LESS_THAN", // [60]
  "EQUALS", // [61]
  "GREATER_THAN", // [62]
  "QUESTION_MARK", // [63]
  "AT", // [64]
  "A", // [65]
  "B", // [66]
  "C", // [67]
  "D", // [68]
  "E", // [69]
  "F", // [70]
  "G", // [71]
  "H", // [72]
  "I", // [73]
  "J", // [74]
  "K", // [75]
  "L", // [76]
  "M", // [77]
  "N", // [78]
  "O", // [79]
  "P", // [80]
  "Q", // [81]
  "R", // [82]
  "S", // [83]
  "T", // [84]
  "U", // [85]
  "V", // [86]
  "W", // [87]
  "X", // [88]
  "Y", // [89]
  "Z", // [90]
  "OS_KEY", // [91] Windows Key (Windows) or Command Key (Mac)
  "", // [92]
  "CONTEXT_MENU", // [93]
  "", // [94]
  "SLEEP", // [95]
  "NUMPAD0", // [96]
  "NUMPAD1", // [97]
  "NUMPAD2", // [98]
  "NUMPAD3", // [99]
  "NUMPAD4", // [100]
  "NUMPAD5", // [101]
  "NUMPAD6", // [102]
  "NUMPAD7", // [103]
  "NUMPAD8", // [104]
  "NUMPAD9", // [105]
  "MULTIPLY", // [106]
  "ADD", // [107]
  "SEPARATOR", // [108]
  "SUBTRACT", // [109]
  "DECIMAL", // [110]
  "DIVIDE", // [111]
  "F1", // [112]
  "F2", // [113]
  "F3", // [114]
  "F4", // [115]
  "F5", // [116]
  "F6", // [117]
  "F7", // [118]
  "F8", // [119]
  "F9", // [120]
  "F10", // [121]
  "F11", // [122]
  "F12", // [123]
  "F13", // [124]
  "F14", // [125]
  "F15", // [126]
  "F16", // [127]
  "F17", // [128]
  "F18", // [129]
  "F19", // [130]
  "F20", // [131]
  "F21", // [132]
  "F22", // [133]
  "F23", // [134]
  "F24", // [135]
  "", // [136]
  "", // [137]
  "", // [138]
  "", // [139]
  "", // [140]
  "", // [141]
  "", // [142]
  "", // [143]
  "NUM_LOCK", // [144]
  "SCROLL_LOCK", // [145]
  "WIN_OEM_FJ_JISHO", // [146]
  "WIN_OEM_FJ_MASSHOU", // [147]
  "WIN_OEM_FJ_TOUROKU", // [148]
  "WIN_OEM_FJ_LOYA", // [149]
  "WIN_OEM_FJ_ROYA", // [150]
  "", // [151]
  "", // [152]
  "", // [153]
  "", // [154]
  "", // [155]
  "", // [156]
  "", // [157]
  "", // [158]
  "", // [159]
  "CIRCUMFLEX", // [160]
  "EXCLAMATION", // [161]
  "DOUBLE_QUOTE", // [162]
  "HASH", // [163]
  "DOLLAR", // [164]
  "PERCENT", // [165]
  "AMPERSAND", // [166]
  "UNDERSCORE", // [167]
  "OPEN_PAREN", // [168]
  "CLOSE_PAREN", // [169]
  "ASTERISK", // [170]
  "PLUS", // [171]
  "PIPE", // [172]
  "HYPHEN_MINUS", // [173]
  "OPEN_CURLY_BRACKET", // [174]
  "CLOSE_CURLY_BRACKET", // [175]
  "TILDE", // [176]
  "", // [177]
  "", // [178]
  "", // [179]
  "", // [180]
  "VOLUME_MUTE", // [181]
  "VOLUME_DOWN", // [182]
  "VOLUME_UP", // [183]
  "", // [184]
  "", // [185]
  "SEMICOLON", // [186]
  "EQUALS", // [187]
  "COMMA", // [188]
  "MINUS", // [189]
  "PERIOD", // [190]
  "SLASH", // [191]
  "BACK_QUOTE", // [192]
  "", // [193]
  "", // [194]
  "", // [195]
  "", // [196]
  "", // [197]
  "", // [198]
  "", // [199]
  "", // [200]
  "", // [201]
  "", // [202]
  "", // [203]
  "", // [204]
  "", // [205]
  "", // [206]
  "", // [207]
  "", // [208]
  "", // [209]
  "", // [210]
  "", // [211]
  "", // [212]
  "", // [213]
  "", // [214]
  "", // [215]
  "", // [216]
  "", // [217]
  "", // [218]
  "OPEN_BRACKET", // [219]
  "BACK_SLASH", // [220]
  "CLOSE_BRACKET", // [221]
  "QUOTE", // [222]
  "", // [223]
  "META", // [224]
  "ALTGR", // [225]
  "", // [226]
  "WIN_ICO_HELP", // [227]
  "WIN_ICO_00", // [228]
  "", // [229]
  "WIN_ICO_CLEAR", // [230]
  "", // [231]
  "", // [232]
  "WIN_OEM_RESET", // [233]
  "WIN_OEM_JUMP", // [234]
  "WIN_OEM_PA1", // [235]
  "WIN_OEM_PA2", // [236]
  "WIN_OEM_PA3", // [237]
  "WIN_OEM_WSCTRL", // [238]
  "WIN_OEM_CUSEL", // [239]
  "WIN_OEM_ATTN", // [240]
  "WIN_OEM_FINISH", // [241]
  "WIN_OEM_COPY", // [242]
  "WIN_OEM_AUTO", // [243]
  "WIN_OEM_ENLW", // [244]
  "WIN_OEM_BACKTAB", // [245]
  "ATTN", // [246]
  "CRSEL", // [247]
  "EXSEL", // [248]
  "EREOF", // [249]
  "PLAY", // [250]
  "ZOOM", // [251]
  "", // [252]
  "PA1", // [253]
  "WIN_OEM_CLEAR", // [254]
  "" // [255]
];

Примітка . Положення кожного значення в масиві вище є важливим. ""Заповнювачі для кодів з невідомими значеннями.

Спробуйте наступний фрагмент коду, використовуючи цей підхід до пошуку статичного масиву ...


Основні коди, які варто зазначити

Літери AZ: (65-90)

keyboardMap[65];  // A
...
keyboardMap[90];  // Z

Цифри 0-9: (48-57)

keyboardMap[48];  // 0
...
keyboardMap[57];  // 9

Цифрова колодка 0-9: (96-105)

keyboardMap[96];   // NUMPAD0
...
keyboardMap[105];  // NUMPAD9

Клавіші зі стрілками: (37-40)

keyboardMap[37];  // LEFT
keyboardMap[38];  // UP
keyboardMap[39];  // RIGHT
keyboardMap[40];  // DOWN

Клавіша вкладки: (9)

keyboardMap[9];  // TAB

Клавіша введення: (13)

keyboardMap[13];  // ENTER

Клавіша пробілу: (32)

keyboardMap[32];  // SPACE

Специфічний ключ ОС (91) Ключ Windows (Windows) або Командний ключ (Mac)

keyboardMap[91];  // OS_KEY

Клавіша Alt: (18)

keyboardMap[18];  // ALT

Клавіша управління: (17)

keyboardMap[17];  // CONTROL

Клавіша Shift: (16)

keyboardMap[16];  // SHIFT

Ключ блокування Caps: (20)

keyboardMap[20];  // CAPS_LOCK

не працює для спеціальних символів, якщо ввести клавіші з клавішею Shift, будь-яке рішення?
Shaik Matheen

14

Лише важлива примітка: прийнята відповідь, наведена вище, не працюватиме правильно для keyCode> = 144, тобто період, кома, тире тощо. Для тих, хто вам слід використовувати більш загальний алгоритм:

let chrCode = keyCode - 48 * Math.floor(keyCode / 48);
let chr = String.fromCharCode((96 <= keyCode) ? chrCode: keyCode);

Якщо вам цікаво, чому це, мабуть, необхідно через поведінку вбудованої функції JS String.fromCharCode(). Для значень keyCode <= 96цього, здається, відображення за допомогою функції:

chrCode = keyCode - 48 * Math.floor(keyCode / 48)

Для значень keyCode > 96цього, здається, відображення за допомогою функції:

chrCode = keyCode

Якщо це здається дивним поведінкою, то добре ... Я згоден. На жаль, це було б дуже далеко від найсмішнішої речі, яку я бачив у ядрі JS.

document.onkeydown = function(e) {
    let keyCode = e.keyCode;
    let chrCode = keyCode - 48 * Math.floor(keyCode / 48);
    let chr = String.fromCharCode((96 <= keyCode) ? chrCode: keyCode);
    console.log(chr);
};
<input type="text" placeholder="Focus and Type"/>


1
Ви збираєтесь плутати людей, використовуючи letвідповідь на питання від 2009 року. :-)
Девід Мердок

12
Якщо хтось виявить ES6, дивлячись вгору, letя зробив їм послугу ;-)
галарант

@galarant Ви можете пояснити, чому / як це працює?
Іжар Аазмі

@IzharAazmi додав пояснення. Сподіваюся, це допомагає!
галарант

1
Він також не працює належним чином для цифрових клавіш на цифровій клавіатурі (сітка клавіш праворуч від розширених клавіатур).
Скотт Бюкенан

2

Я припускаю, що це для гри або для швидкого реагування типу додатків, отже, використання KEYDOWN, ніж KEYPRESS.

Редагувати : Данг! Я виправлений (дякую Crescent Fresh та David): JQuery (а точніше, основні господарі DOM) не розкривають деталі WM_KEYDOWN та інших подій. Швидше вони попередньо перетравлюють ці дані, і у випадку з KeyDown навіть у JQuery ми отримуємо:

Зауважте, що ці властивості є значеннями UniCode.
Зауважте, мені не вдалося знайти авторитетного посилання на це в документах JQuery, але багато поважних прикладів в мережі стосуються цих двох властивостей.

Наступний код, адаптований з мого Java (не JavaScript), тому абсолютно невірний ...

Далі наведено "цікаві" частини ключового коду:

  value = e.KeyCode;
  repeatCount = value & 0xFF;
  scanCode = (value >> 16) & 0xFF;  // note we take the "extended bit" deal w/ it later.
  wasDown = ((value & 0x4000) != 0);  // indicate key was readily down (auto-repeat)
  if (scanCode > 127)
      // deal with extended
  else
      // "regular" character

хм, не йдіть, scanCode завжди призводить до 0. А e.KeyCode має бути e.keyCode (KeyCode не визначено).
Девід Мердок

Гей, зараз ... Привіт, почекай ... Ми говоримо тут про JScript чи щось таке?
Півмісяць Свіжий

@David M. Мої погані, можливо, JQuery "попередньо перетравлює" ці кодові частини для нас. Я зараз розглядаю це.
mjv

1
@mjv: звідки ти взяв цей код? Це коли-небудь спрацювало для вас? Реалізація AFAIK no DOM кодує всю цю інформацію в об'єкт події ( keydownчи ні).
Півмісяць Свіжий

@Crescent: Я швидко та наївно адаптував це з мого коду Java, який у мене вже давній ... У будь-якому випадку, ви абсолютно праві: жоден з DOM не влаштовує жодних подібних сирих подій, навіть для клавіатури. Я відповідно зафіксував свою прозу; все ще шукаю авторитетного документа на цю тему від JQuery.com
mvv

0

Я знаю, що це давнє питання, але я сьогодні натрапив на нього, шукаючи заздалегідь упаковане рішення цієї проблеми, і не знайшов нічого, що насправді відповідало б моїм потребам.

Ось рішення (лише англійською мовою), яке правильно підтримує верхній регістр (зміщений), нижній регістр, пунктуацію, цифрову клавіатуру тощо.

Він також дозволяє просте ідентифікацію та реакцію на недруковані клавіші, наприклад ESC, стрілки, функціональні клавіші тощо.

https://jsfiddle.net/5hhu896g/1/

keyboardCharMap and keyboardNameMap are the key to making this work

Дякую DaveAlger, що врятував мене набравши текст - і багато відкриття! - надавши масив іменованих ключів.


Ваша загадка найвидатніша! Дякую, що поділились. Це чудово працює. Я використовую його для впровадження редагування мульти курсору в стилі Sublime для полів форми з елементами, що мають однакові значення
Todd Hammer

0

Нещодавно я написав модуль під назвою keysight , який транслює keypress, keydownі keyupподії в символи і ключі відповідно.

Приклад:

 element.addEventListener("keydown", function(event) {
    var character = keysight(event).char
 })

чи підтримує він клавіші на зразок -?
Арнольд Роа

@ArnoldRoa Я просто штовхнув щось, що, сподіваюсь, підтримає таких персонажів. У мене немає клавіатури з наголошеними символами, тож ви б заперечили тестування?
BT

0

Для тих із вас, хто прийшов сюди, шукаючи фактичні значення символів Unicode для ключового коду, як і я, ось функція для цього. Наприклад, якщо вказати код коду unicode клавіші правої стрілки, це виведе видимий рядок\u001B\u005B\u0043

function toUnicode(theString) {
    var unicodeString = '';
    for (var i = 0; i < theString.length; i++) {
        var theUnicode = theString.charCodeAt(i).toString(16).toUpperCase();
        while (theUnicode.length < 4) {
            theUnicode = '0' + theUnicode;
        }
        theUnicode = '\\u' + theUnicode;
        unicodeString += theUnicode;
    }
    return unicodeString;
}

0

Ви також можете використовувати властивість лише для читання key. Він також поважає спеціальні ключі на кшталтshift etc., і підтримується IE9.

При натисканні символу, який не друкується або спеціального символу, значення буде визначатись із визначених ключових значень, таких як 'Shift'або 'Multiply'.

  • Клавіатура     event.key
  • X             -> 'x'
  • Shift+ X ->'X'
  • F5            -> 'F5'

-2

Перейдіть за цим посиланням Отримати Keycode від натискання клавіш і значення знаку для будь-якого коду ключа

$('input#inp').keyup(function(e){
   $(this).val(String.fromCharCode(e.keyCode)); 
   $('div#output').html('Keycode : ' + e.keyCode);  
});

1
Це неправильно! Оскільки він не враховує поточну мову, включену на клавіатурі користувача. Наприклад, я ввожу "ф", але це дає "а" ...
Вадим Гузев

це неправильно, текст змінюватиметься відповідно до макета клавіатури
Арнольд Роа
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.