onKeyPress Vs. onKeyUp та onKeyDown


329

Яка різниця між цими трьома подіями? Після гугла я виявив, що:

  • onKeyDownПодія спрацьовує , коли користувач натискає кнопку.
  • onKeyUpПодія спрацьовує , коли користувач відпускає клавішу.
  • onKeyPressПодія спрацьовує , коли преса і користувач відпускає ключ ( з onKeyDownподальшим onKeyUp).

Я розумію перші два, але чи не onKeyPressте саме onKeyUp? Чи можливо випустити ключ ( onKeyUp), не натискаючи його ( onKeyDown)?

Це трохи заплутано, чи може хтось мені це очистити?


3
Я виявив, що якщо я утримую клавішу TAB вниз, вона безперервно перемикається по всіх полях і запускає лише “onkeydown”.
nu everest

23
подія натискання клавіші представляє символ, який вводиться, який може бути використаний для введення даних, таких як 'a', 'D', '£', '©' тощо. З іншого боку, події клавіатури та клавіатури являють собою будь-які ключі, які вводяться, що включає такі речі, як зворотна область, вкладка, вгору, вниз, домашня сторінка, кінець тощо.
skcin7

2
"(чи можна відпустити ключ (KeyUp), не натискаючи (KeyDown) це?)" - Так. Наприклад, клавіша вкладки: подія клавіатури може бути не захоплена тим самим елементом, що і клавіша.
Self Evident

Відповіді:


191

Ознайомтесь із архівним посиланням, яке спочатку було використано у цій відповіді.

З цього посилання:

Теоретично, onKeyDownі onKeyUpподії представляють клавіші, які натискаються або відпускаються, тоді як onKeyPressподія представляє символ, який вводиться. Реалізація теорії однакова у всіх браузерах.


18
Складіть jsfiddle на основі публікації @ Falk, щоб продемонструвати свої ідіосинхронності (використовуючи jquery): jsfiddle.net/zG9MF/2
fordareh

Я не бачу пов'язаної сторінки, але пункт про те, що "персонаж вводиться" є важливим, якщо ви плануєте використовувати це для будь-якого типу перевірки. Подія натискання клавіші не спрацьовує, коли користувач видаляє символ, тому ваша перевірка не запуститься.
Тоні Мерріфілд

@Tony Merryfield - посилання для мене працює добре, я просто перевірив його ще раз.
dcp

1
@dcp - Так, було достатньо натяку, щоб вивести мене на правильний шлях. Я щойно додав свій коментар, щоб підкреслити те, що подія спрацьовує лише тоді, коли персонаж набирається на відміну від будь-якого натискання клавіші - ви отримали моє оновлення;)
Тоні Мерріфілд,

1
Крім того, при "довгому" натисканні клавіші подія KeyDown продовжує спрацьовувати, поки ключ не буде випущений, і тоді KeyUp буде випущено лише один раз;)
Bernoulli IT

195

KeyPress, KeyUpІ KeyDownаналогічні, відповідно: Click, MouseUp,і MouseDown.

  1. Down відбувається спочатку
  2. Press трапляється другий (при введенні тексту)
  3. Up відбувається останнім (коли введення тексту завершено).

Виняток - webkit , у якому є додаткова подія:

keydown
keypress
textInput     
keyup

Нижче наведено фрагмент, який ви можете використати, щоб побачити, коли події будуть звільнені:

window.addEventListener("keyup", log);
window.addEventListener("keypress", log);
window.addEventListener("keydown", log);

function log(event){
  console.log( event.type );
}


1
Отже, чи KeyPress - це лише додаткова подія, що стосується б / у KeyDown та TextInput? Як це (KeyPress) зазвичай використовують розробники?
моментальнасуна

78
Найкраща відповідь +1 - * Вниз відбувається по-перше, * Натискання відбувається друге (коли текст вводиться), а * Вгору відбувається останнім (коли введення тексту завершено).
Скотт Пелак

2
-1 тому, що невелике експериментування у фрагменті суперечить вашій аналогії з подією "клацання". Подія "клацання" спрацьовує одночасно з "мишею" (коли ви відпускаєте кнопку миші), але подія "натискання клавіші" спрацьовує одночасно з "натисканням клавіші" (при першому натисканні клавіші).
Марк Амері

2
@Robusto Насправді, keypressі keydownподіям буквально присвоюється одне і те ж .timeStampзначення, яке точно в інтервалах 5 мікросекунд, але це все-таки не моє значення. Моя думка полягає в тому, що clickподія не спрацьовує, поки ви не відпустите кнопку миші, тому мовляв, що keypressсаме версія клавіатури clickробить так, що звук не keypressбуде запускатися, поки ви не відпустите ключ. Насправді це не так: він спрацьовує при натисканні ключа, як keydownі у випадку. Тож keypressнасправді це зовсім не аналогічно click.
Марк Амері

2
@Robusto "як ви пояснюєте, що" натискання клавіші "завжди записується після" клавіші " - просто: та сама дія користувача (натискання на клавішу) негайно запускає обох обробників, щоб їх було переведено у чергу подій, але у фіксованому порядку . "ви просто хочете мати аргумент заради аргументу" - Так? Ядро тезу вашої відповіді полягає в тому , що keypress, keyupі keydownаналогічні click, mouseupі mousedown. Природною інтерпретацією цього, як на мене, є те, що він keypressвипалює в ту ж мить, що і keyup(як clickі як mouseup). Що ж ви маєте в виду, якщо не це?
Марк Амері

23

Більшість відповідей тут зосереджені більше на теорії, ніж на практичних питаннях, і є деякі великі відмінності між keyupі, keypressяк це стосується значень поля введення, принаймні у Firefox (перевірено у 43).

Якщо користувач вводить 1порожній вхідний елемент:

  1. Значенням елемента введення буде порожній рядок (старе значення) всередині keypressобробника

  2. Значення вхідного елемента буде 1 (нове значення) всередині keyupобробника.

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

Сценарій:

  1. Типи користувачів 12345 вхідний елемент.
  2. Користувач вибирає текст 12345 .
  3. Користувач набирає лист A.

Коли keypressподія запускається після введення листа A, текстове поле тепер містить лише буквуA .

Але:

  1. Field.val () є 12345 .
  2. $ Field.val (). Довжина - 5
  3. Вибір користувача - це порожній рядок (заважаючи визначити, що було видалено, перезаписавши вибір).

Отже, здається, що браузер (Firefox 43) стирає вибір користувача, потім запускає keypressподію, потім оновлює вміст полів, потім запускає keyup.


16

onkeydownзапускається, коли ключ не працює (як, наприклад, у ярликах; наприклад, у Ctrl+A,Ctrl утримується "вниз"

onkeyup запускається, коли ключ випущений (включаючи модифікатор / клавіші тощо)

onkeypressзапускається як комбінація onkeydownта onkeyup, або залежно від повторення клавіатури (колиonkeyup не запускається). (ця повторна поведінка - те, що я не перевіряв. Якщо ви робите тест, додайте коментар!)

textInput(лише webkit) запускається, коли вводиться якийсь текст (наприклад, Shift+Aвводиться верхній регістр "A", але Ctrl+Aвибирається текст і не вводиться жодне введення тексту. У такому разі всі інші події запускаються)


1
Щойно підтверджено, що насправді "натискання клавіші" викликається повторно, коли клавіша утримується, і відбувається "повтор клавіатури". Однак це справедливо і для "onkeydown"! (що несподівано, давши назву)
Венрікс

11

По-перше, вони мають різне значення: вони стріляють:

  • KeyDown - коли ключ був натиснута вниз
  • KeyUp - коли кнопка натиснута була випущена , і після того, як того, як значення введення / текстове поле оновлюється (тільки один з них)
  • KeyPress - між цими і насправді не означає, що була натиснута та відпущена клавіша (див. Нижче).

По-друге, деякі клавіші запускають деякі з цих подій, а інші не запускають . Наприклад,

  • KeyPress ігнорує delete, стрілки, PgUp/ PgDn, home/ end, ctrl,alt , і shiftт.д. , а KeyDown і KeyUp ні (див подробиці проesc нижче);
  • коли ви перемикаєте вікно через alt+ tabу Windows, для altпожеж лише KeyDown, оскільки перемикання вікон відбувається перед будь-якою іншою подією (і KeyDown дляtab системи, , перешкоджає, принаймні, в Chrome 71).

Крім того, слід пам’ятати, що event.keyCodeevent.which) зазвичай мають однакове значення для KeyDown та KeyUp, але різні для KeyPress. Спробуйте майданчик, який я створив. До речі, я помітив досить химерність: у Chrome, коли я натискаю ctrl+, aа input/ textareaпорожній, для KeyPress спрацьовує event.keyCodeevent.which), що дорівнює 1! (коли вхід не порожній, він взагалі не спрацьовує).

Нарешті, є деякі прагматики :

  • Для обробки стрілок, ймовірно, потрібно буде використовувати onKeyDown: якщо користувач тримає , KeyDown спрацьовує кілька разів (тоді як KeyUp спрацьовує лише один раз, коли вони відпускають кнопку). Крім того, в деяких випадках ви можете легко запобігти поширенню KeyDown, але не можете (або не можете це легко) запобігти розповсюдженню KeyUp (наприклад, якщо ви хочете подати на введення, не додаючи нову рядок у текстове поле).
  • Дивно, коли ви тримаєте ключ, скажіть textarea , і KeyPress, і KeyDown стріляють кілька разів (Chrome 71), я б використовував KeyDown, якщо мені потрібна подія, яка запускається кілька разів, і KeyUp для одного випуску ключа.
  • KeyDown, як правило, краще для ігор, коли вам потрібно забезпечити кращу реакцію на їх дії.
  • escзазвичай обробляється за допомогою KeyDown: KeyPress не спрацьовує, а KeyUp поводиться по-різному для inputs таtextarea s в різних браузерах (в основному через втрату фокусу)
  • Якщо ви хочете відрегулювати висоту області тексту до вмісту, ви, ймовірно, не будете використовувати OnKeyDown, а скоріше onKeyPress ( PS добре, насправді краще використовувати для цього випадку onChange ).

Я використав усі 3 у своєму проекті, але, на жаль, можливо, забув частину прагматики. (зауважимо: є також inputі changeподії)


Я не думав над тим, щоб клавіатура додала новий рядок до вмісту поля, але це насправді важливо.
FKEinternet

10

Ця стаття Яни Вольтер кращий шматок я натрапив, ви можете знайти архівну копію тут , якщо посилання мертва.

Це дуже добре пояснює всі ключові події браузера,

KeyDown подія відбувається при натисканні на клавішу, а потім відразу ж подія натискання клавіші. Потім клавіатура подія генерується при ключа.

Щоб зрозуміти різницю між клавіатурою та натисканням клавіші , корисно розрізняти символи та клавіші . Ключ є фізичною кнопкою на клавіатурі комп'ютера. Символ є символом набраний натисканням кнопки. На клавіатурі в США натискання 4клавіші, утримуючи Shiftклавішу, зазвичай видає символ "знак долара". Це не обов'язково має місце на кожній клавіатурі у світі. Теоретично подія клавіш і клавіш події являють собою ключі натиснуті або відпущені, в той час як натискання клавіші представляє символ, який вводиться. На практиці це не завжди так, як це реалізується.

Деякий час броузери одразу після натискання клавіші розпочали додаткову подію під назвою textInput . Ранні версії стандарту DOM 3 передбачали це як заміну події натискання клавіші , але все поняття пізніше було відкликано. Webkit підтримував це між версіями 525 та 533, і мені кажуть, IE підтримував це, але я ніколи цього не виявляв , можливо, тому, що Webkit вимагав, щоб його називали textInput, тоді як IE називав це textinput .

Існує також подія під назвою введення , підтримувана всіма браузерами, яка запускається відразу після внесення змін у поле текстової області або поля введення. Зазвичай натискання клавіші буде спрацьовувати, тоді введений символ з'явиться в текстовій області, після чого введення запуститься. Вхід подія фактично не дає ніякої інформації про те, що було надруковано ключ - ви повинні перевірити текстове поле , щоб зрозуміти це , що змінилося - так що ми на самому ділі не вважаємо це ключовою подією і справді не документувати його тут . Хоча він спочатку був визначений лише для текстових областей та полів для введення даних, я вважаю, що є певний рух у напрямку узагальнення його для стрільби по інших типах об'єктів.


Найкраща відповідь, то як ви можете отримати, скажімо, символ знака долара від натискання клавіші?
bluejayke

10

Здається, що onkeypress та onkeydown роблять те ж саме (при невеликій різниці клавіш швидкого доступу, про які вже говорилося вище).

Ви можете спробувати це:

<textarea type="text" onkeypress="this.value=this.value + 'onkeypress '"></textarea>
<textarea type="text" onkeydown="this.value=this.value + 'onkeydown '" ></textarea>
<textarea type="text" onkeyup="this.value=this.value + 'onkeyup '" ></textarea>

І ви побачите, що події onkeypress та onkeydown ініціюються під час натискання клавіші, а не при натисканні клавіші.

Різниця полягає в тому, що подія спрацьовує не один раз, а багато разів (поки ви утримуєте натиснуту клавішу). Будьте в курсі цього і поводьтеся з ними відповідно.


Ctrl, Shift, CapsLock, Backspace та інші клавіші, які щось не набирають, не викликаютьkeypress події, але вони завжди викликають a keydown.
CPHPython

8

Подія onkeypress працює для всіх клавіш, крім ALT, CTRL, SHIFT, ESC у всіх браузерах, де як подія onkeydown працює для всіх клавіш. Значить подія onkeydown захоплює всі клавіші.


натискання клавіш також ігнорує видалення, стрілки, головна / кінцева, PgUp / PgDn, див. мою відповідь для деталей (ви можете також оновити свою відповідь)
YakovL

4

Просто хотілося поділитися цікавістю:

при використанні події onkeydown для активації методу JS, код коду для цієї події НЕ такий, як той, який ви отримуєте за допомогою onkeypress!

Наприклад, клавіші numpad повертають ті самі коди, що і цифрові клавіші над буквеними клавішами при використанні натискання клавіш, але НЕ під час використання клавіші onkeydown!

У мене знадобилося досить декількох секунд, щоб зрозуміти, чому мій сценарій, який перевіряв певні шаблони, не вдався при використанні onkeydown!

Демонстраційна версія: https://www.w3schools.com/code/tryit.asp?filename=FMMBXKZLP1MK

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


Схоже, що для 0123456789
Числового символу

А ви помітили, що keyDown дає КЛЮЧ на клавіатурі, тоді як keyPress дає точний персонаж, який ми щойно набрали (або натиснули)
Mrigank Pawagi

2

В основному ці події діють по-різному в різних типах і версії браузера, я створив невеликий тест jsBin, і ви можете перевірити консоль, щоб дізнатися, як поведінка цих подій у вашому цільовому середовищі, сподіваюся, що це допоможе. http://jsbin.com/zipivadu/10/edit


1

Оновлений відповідь:

KeyDown

  • Створюється кілька разів при натисканні клавіш.
  • Запускає мета-ключ.

KeyPress

  • Створюється кілька разів при натисканні клавіш.
  • Хіба НЕ спрацьовує мета ключі.

KeyUp

  • Запускається один раз наприкінці, коли ви відпускаєте ключ.
  • Запускає мета-ключ.

Така поведінка і в addEventListenerі jQuery.

https://jsbin.com/vebaholamu/1/edit?js,console,output <- спробуйте

показаний приклад із утримуванням для SSS

(відповідь відредаговано з правильною відповіддю, скріншотом та прикладом)


За винятком клавіатури, яка спрацьовує декілька разів
bluejayke

-1, тому що принаймні одна деталь щодо цього неправильна принаймні у Chrome; як говорить @bluejayke, KeyDown також кілька разів спрацьовує, коли ви утримуєте клавішу.
Марк Амері

Так, хлопці, ви праві, вибачте за мою помилку; відповідь відредагована.
Куанг Ван

0

Кілька практичних фактів, які можуть бути корисними для вирішення, з якою подією обробляти (запустіть сценарій нижче та зосередьтеся на полі введення):

$('input').on('keyup keydown keypress',e=>console.log(e.type, e.keyCode, e.which, e.key))
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<input/>

Натискання:

  • клавіші, які не вставляють / набирають (наприклад Shift, Ctrl), не спрацьовують a keypress. Натисніть Ctrlта відпустіть його:

    клавіш 17 17 Керування

    клавіатура 17 17 Керування

  • клавіші з клавіатур, які застосовують перетворення символів до інших символів, можуть призводити до " мертвих" і дублювати "клавіші" (наприклад ~, ´) на keydown. Натисніть ´та відпустіть його, щоб відобразити подвійне ´´:

    натискання клавіш 192 192 мертвих

    клавіша 192 192 ´´

    клавіша 180 180 ´

    клавіша 180 180 ´

    клавіатура 192 192 мертвих

Крім того, <input type="range">невведення тексту (наприклад, діапазон ) все ще викликатиме всі події клавіш, клавіш та натискання клавіш відповідно до натиснутих клавіш.

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