onKeyPress Vs. onKeyUp và onKeyDown


329

Sự khác biệt giữa ba sự kiện này là gì? Khi googling tôi thấy rằng:

  • Sự onKeyDownkiện được kích hoạt khi người dùng nhấn phím.
  • Sự onKeyUpkiện được kích hoạt khi người dùng phát hành khóa.
  • Sự onKeyPresskiện được kích hoạt khi người dùng nhấn và nhả một phím ( onKeyDowntheo sau onKeyUp).

Tôi hiểu hai cái đầu tiên, nhưng không onKeyPressgiống như onKeyUp? Có thể phát hành một khóa ( onKeyUp) mà không cần nhấn nó ( onKeyDown)?

Điều này hơi khó hiểu, ai đó có thể làm rõ điều này cho tôi không?


3
Tôi thấy rằng nếu tôi giữ phím TAB xuống thì nó sẽ liên tục quay vòng qua tất cả các trường và chỉ kích hoạt 'onkeydown'.
nu everest

23
sự kiện nhấn phím biểu thị một ký tự được gõ có thể được sử dụng cho đầu vào, chẳng hạn như 'a', 'D', '£', '©', v.v. Mặt khác, các sự kiện keydown và keyup đại diện cho BẤT K key phím nào được gõ, bao gồm những thứ như backspace, tab, lên, xuống, home, end, v.v.
skcin7

2
"(hoặc có thể phát hành khóa (KeyUp) mà không cần nhấn (KeyDown) không?)" - Có. Ví dụ: phím tab: sự kiện keyup có thể không được ghi lại bởi cùng một yếu tố với phím tắt.
Tự chứng minh

Câu trả lời:


191

Kiểm tra ở đây cho các liên kết lưu trữ ban đầu được sử dụng trong câu trả lời này.

Từ liên kết đó:

Về lý thuyết, các sự kiện onKeyDownonKeyUpđại diện cho các phím được nhấn hoặc phát hành, trong khi onKeyPresssự kiện đại diện cho một nhân vật được gõ. Việc thực hiện lý thuyết là không giống nhau trong tất cả các trình duyệt.


18
Kết hợp một jsfiddle dựa trên bài đăng của @ Falk để chứng minh các idiosynchracies (sử dụng jquery): jsfiddle.net/zG9MF/2
fordareh

Tôi không thể thấy trang được liên kết nhưng điểm về 'một ký tự được nhập' là một trang quan trọng nếu bạn dự định sử dụng trang này cho bất kỳ loại xác nhận nào. Sự kiện nhấn phím không kích hoạt khi người dùng xóa một ký tự, vì vậy xác thực của bạn sẽ không kích hoạt.
Tony Merryfield

@Tony Merryfield - link đang hoạt động tốt với tôi, tôi chỉ cần kiểm tra lại.
dcp

1
@dcp - Vâng, đã đủ gợi ý để đưa tôi đi đúng hướng. Tôi vừa thêm nhận xét của mình để củng cố quan điểm rằng sự kiện chỉ kích hoạt khi một nhân vật được gõ trái ngược với bất kỳ phím bấm nào - bạn đã nhận được sự ủng hộ của tôi;)
Tony Merryfield

1
Ngoài ra, trên một lần nhấn phím "dài", sự kiện KeyDown sẽ tiếp tục kích hoạt cho đến khi khóa được phát hành trong trường hợp KeyUp chỉ được kích hoạt một lần;)
Bernoulli IT

195

KeyPress, KeyUpKeyDownlà tương tự, tương ứng: Click, MouseUp,MouseDown.

  1. Down xảy ra đầu tiên
  2. Press xảy ra lần thứ hai (khi văn bản được nhập)
  3. Up xảy ra lần cuối (khi nhập văn bản hoàn tất).

Ngoại lệ là webkit , có một sự kiện bổ sung trong đó:

keydown
keypress
textInput     
keyup

Dưới đây là đoạn trích bạn có thể sử dụng để tự mình xem khi các sự kiện được kích hoạt:

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

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


1
Vậy, có phải KeyPress chỉ là một sự kiện bổ sung mà b / w KeyDown và TextInput không? Làm thế nào nó (KeyPress) thường được sử dụng bởi các nhà phát triển?
instantsetsuna

78
Câu trả lời hay nhất +1 - * Xuống xảy ra trước, * Bấm xảy ra lần thứ hai (khi văn bản được nhập) và * Lên xảy ra lần cuối (khi nhập văn bản hoàn tất).
Scott Pelak

2
-1 vì một thử nghiệm nhỏ trong đoạn trích mâu thuẫn với sự tương tự của bạn với sự kiện 'nhấp chuột'. Sự kiện 'click' kích hoạt cùng lúc với 'mouseup' (khi bạn nhả nút chuột), nhưng sự kiện 'nhấn phím' sẽ kích hoạt cùng lúc với 'phím tắt' (khi phím được ấn lần đầu tiên).
Đánh dấu Amery

2
@Robusto Trên thực tế, các sự kiện keypresskeydowncác sự kiện theo nghĩa đen được gán cùng một .timeStampgiá trị, chính xác với các khoảng thời gian là 5 micro giây, nhưng dù sao đó không thực sự là quan điểm của tôi. Quan điểm của tôi là clicksự kiện này không kích hoạt cho đến khi bạn nhả nút chuột, do đó, nói rằng đó keypresslà phiên bản bàn phím clickkhiến âm thanh giống như keypressvậy sẽ không kích hoạt cho đến khi bạn nhả phím. Trên thực tế, đó không phải là trường hợp: nó kích hoạt khi phím bị đè, giống như keydownvậy. Vì vậy, keypresstrên thực tế không giống với clicktất cả.
Đánh dấu Amery

2
@Robusto "làm thế nào để bạn giải thích 'phím bấm' luôn được ghi lại sau 'phím tắt'" - đơn giản: cùng một hành động của người dùng (nhấn phím xuống) ngay lập tức kích hoạt cả hai trình xử lý được đẩy vào hàng đợi sự kiện, nhưng theo thứ tự cố định . "Bạn chỉ muốn có một cuộc tranh luận vì lợi ích của cuộc tranh luận" - Eh? Luận án cốt lõi của câu trả lời của bạn là keypress, keyupkeydownlà tương tự click, mouseupmousedown. Theo tôi, cách giải thích tự nhiên đó là keypressbắn vào cùng một lúc với keyup(giống như clickmouseup). Có gì không bạn có nghĩa là, nếu không muốn nói đó?
Đánh dấu Amery

23

Hầu hết các câu trả lời ở đây tập trung nhiều vào lý thuyết hơn là các vấn đề thực tế và có một số khác biệt lớn giữa keyupkeypressvì nó liên quan đến các giá trị trường đầu vào, ít nhất là trong Firefox (được thử nghiệm trong 43).

Nếu người dùng 1nhập vào một phần tử đầu vào trống:

  1. Giá trị của phần tử đầu vào sẽ là một chuỗi rỗng (giá trị cũ) bên trong keypresstrình xử lý

  2. Giá trị của phần tử đầu vào sẽ là 1(giá trị mới) bên trong keyuptrình xử lý.

Điều này có tầm quan trọng quan trọng nếu bạn đang làm một cái gì đó dựa vào việc biết giá trị mới sau đầu vào thay vì giá trị hiện tại như xác thực nội tuyến hoặc tự động gắn thẻ.

Kịch bản:

  1. Người dùng 12345nhập vào một yếu tố đầu vào.
  2. Người dùng chọn văn bản 12345.
  3. Người dùng gõ chữ cái A.

Khi keypresssự kiện kích hoạt sau khi nhập chữ cái A, hộp văn bản giờ chỉ chứa chữ cái A.

Nhưng:

  1. Trường.val () là 12345.
  2. $ Field.val (). Độ dài là 5
  3. Lựa chọn của người dùng là một chuỗi trống (ngăn bạn xác định những gì đã bị xóa bằng cách ghi đè lựa chọn).

Vì vậy, có vẻ như trình duyệt (Firefox 43) xóa lựa chọn của người dùng, sau đó kích hoạt keypresssự kiện, sau đó cập nhật nội dung các trường, sau đó kích hoạt keyup.


16

onkeydownđược kích hoạt khi phím bị tắt (như trong các phím tắt; ví dụ: trong Ctrl+A, Ctrlđược giữ 'xuống'.

onkeyup được kích hoạt khi khóa được giải phóng (bao gồm các phím bổ trợ / etc)

onkeypressđược bắn dưới dạng kết hợp onkeydownonkeyup, hoặc tùy thuộc vào lặp lại bàn phím (khi onkeyupkhông được kích hoạt). (hành vi lặp lại này là điều mà tôi chưa kiểm tra. Nếu bạn kiểm tra, hãy thêm nhận xét!)

textInput(chỉ bộ webkit) được kích hoạt khi một số văn bản được nhập (ví dụ: Shift+Asẽ nhập chữ hoa 'A', nhưng Ctrl+Asẽ chọn văn bản và không nhập bất kỳ kiểu nhập văn bản nào. Trong trường hợp đó, tất cả các sự kiện khác được kích hoạt)


1
Chỉ cần xác nhận rằng, thực sự, "onkeypress" được gọi liên tục khi phím được giữ và "lặp lại bàn phím" xảy ra. Tuy nhiên, điều này cũng đúng với "onkeydown"! (thật bất ngờ, được đặt tên)
Venryx

11

Đầu tiên, chúng có ý nghĩa khác nhau: chúng bắn:

  • KeyDown - khi một phím được đẩy xuống
  • KeyUp - khi một nút ấn được phát hànhsau khi giá trị của đầu vào / textarea được cập nhật (chỉ một trong số này)
  • KeyPress - giữa những cái đó và không thực sự có nghĩa là một khóa được đẩy và phát hành (xem bên dưới).

Thứ hai, một số phím bắn một số sự kiện này và không bắn những sự kiện khác . Ví dụ,

  • Bỏ qua của KeyPress delete, mũi tên, PgUp/ PgDn, home/ end, ctrl, alt, shiftvv trong khi KeyDown và KeyUp không (xem chi tiết về escdưới đây);
  • Khi bạn chuyển đổi cửa sổ qua alt+ tabtrong Windows, chỉ KeyDown bị altcháy vì chuyển đổi cửa sổ xảy ra trước bất kỳ sự kiện nào khác (và KeyDown tabbị ngăn chặn bởi hệ thống, tôi cho rằng, ít nhất là trong Chrome 71).

Ngoài ra, bạn nên nhớ rằng event.keyCode(và event.which) thường có cùng giá trị cho KeyDown và KeyUp nhưng khác với KeyPress. Hãy thử sân chơi tôi đã tạo. Nhân tiện, tôi đã nhận thấy một điều khá khó hiểu: trong Chrome, khi tôi nhấn ctrl+ ainput/ textareatrống, vì KeyPress sẽ kích hoạt event.keyCode(và event.which) bằng 1! (khi đầu vào không trống, nó hoàn toàn không kích hoạt).

Cuối cùng, có một số người thực dụng :

  • Để xử lý các mũi tên, có thể bạn sẽ cần sử dụng onKeyDown: nếu người dùng giữ , KeyDown sẽ bắn nhiều lần (trong khi KeyUp chỉ bắn một lần khi họ nhả nút). Ngoài ra, trong một số trường hợp, bạn có thể dễ dàng ngăn chặn việc truyền KeyDown nhưng không thể (hoặc không thể dễ dàng) ngăn chặn việc truyền KeyUp (ví dụ: nếu bạn muốn gửi khi nhập mà không cần thêm dòng mới vào trường văn bản).
  • Đáng ngạc nhiên, khi bạn giữ một khóa, giả sử textarea, cả KeyPress và KeyDown đều bắn nhiều lần (Chrome 71), tôi sẽ sử dụng KeyDown nếu tôi cần sự kiện kích hoạt nhiều lần và KeyUp để phát hành khóa đơn.
  • KeyDown thường tốt hơn cho các trò chơi khi bạn phải cung cấp khả năng phản hồi tốt hơn cho hành động của họ.
  • escthường được xử lý thông qua KeyDown: KeyPress không kích hoạt và KeyUp hoạt động khác nhau đối với inputs và textareas trong các trình duyệt khác nhau (chủ yếu là do mất tập trung)
  • Nếu bạn muốn điều chỉnh chiều cao của vùng văn bản với nội dung, có lẽ bạn sẽ không sử dụng onKeyDown mà thay vào đó là onKeyPress ( PS ok, thực sự tốt hơn khi sử dụng onChange cho trường hợp này ).

Tôi đã sử dụng cả 3 trong dự án của mình nhưng rất tiếc có thể đã quên một số tính thực dụng. (cần lưu ý: cũng có inputchangecác sự kiện)


Tôi đã không nghĩ về việc keyup thêm dòng mới vào nội dung trường, nhưng điều đó thực sự quan trọng.
FKEiNET

10

Bài viết này của Jan Wolter là tác phẩm hay nhất tôi từng gặp, bạn có thể tìm thấy bản sao lưu trữ ở đây nếu liên kết đã chết.

Nó giải thích tất cả các sự kiện quan trọng của trình duyệt thực sự tốt,

Sự kiện nhấn phím xảy ra khi nhấn phím, ngay sau đó là sự kiện nhấn phím. Sau đó, sự kiện keyup được tạo khi khóa được phát hành.

Để hiểu sự khác biệt giữa phím tắtphím bấm , rất hữu ích để phân biệt giữa các ký tựphím . Một chìa khóa là một nút vật lý trên bàn phím của máy tính. Một ký tự là một biểu tượng được gõ bằng cách nhấn một nút. Trên bàn phím Hoa Kỳ, nhấn 4phím trong khi giữ Shiftphím thường tạo ra ký tự "ký hiệu đô la". Điều này không nhất thiết là trường hợp trên mọi bàn phím trên thế giới. Về lý thuyết, các sự kiện keydownkeyup đại diện cho các phím được nhấn hoặc nhả, trong khi nhấn phímsự kiện đại diện cho một nhân vật được gõ. Trong thực tế, điều này không phải lúc nào cũng được thực hiện.

Trong một thời gian, một số trình duyệt đã kích hoạt một sự kiện bổ sung, được gọi là textInput , ngay sau khi nhấn phím . Các phiên bản ban đầu của tiêu chuẩn DOM 3 dự định đây là sự thay thế cho sự kiện nhấn phím , nhưng toàn bộ khái niệm này sau đó đã bị thu hồi. Webkit hỗ trợ điều này giữa các phiên bản 525 và 533 và tôi đã nói với IE đã hỗ trợ nó, nhưng tôi chưa bao giờ phát hiện ra điều đó, có thể vì Webkit yêu cầu nó phải được gọi là textInput trong khi IE gọi nó là textinput .

Ngoài ra còn có một sự kiện được gọi là đầu vào , được hỗ trợ bởi tất cả các trình duyệt, được kích hoạt ngay sau khi thay đổi được thực hiện đối với vùng văn bản hoặc trường đầu vào. Thông thường nhấn phím sẽ kích hoạt, sau đó ký tự được gõ sẽ xuất hiện trong vùng văn bản, sau đó nhập sẽ kích hoạt. Sự kiện đầu vào không thực sự cung cấp bất kỳ thông tin nào về khóa được nhập - bạn phải kiểm tra hộp văn bản để tìm ra sự thay đổi - vì vậy chúng tôi không thực sự coi đó là sự kiện chính và không thực sự ghi lại ở đây . Mặc dù ban đầu nó chỉ được định nghĩa cho textareas và hộp đầu vào, tôi tin rằng có một số chuyển động trong việc khái quát hóa nó để bắn vào các loại đối tượng khác.


Câu trả lời hay nhất, vậy làm thế nào bạn có thể nhận được, nói, biểu tượng ký hiệu đô la từ phím bấm?
bluejayke

10

Có vẻ như onkeypress và onkeydown cũng làm như vậy (với sự khác biệt nhỏ của các phím tắt đã được đề cập ở trên).

Bạn có thể thử điều này:

<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>

Và bạn sẽ thấy rằng các sự kiện onkeypress và onkeydown đều được kích hoạt trong khi phím được nhấn chứ không phải khi nhấn phím.

Sự khác biệt là sự kiện được kích hoạt không chỉ một lần mà nhiều lần (miễn là bạn nhấn phím). Hãy nhận ra điều đó và xử lý chúng cho phù hợp.


Ctrl, Shift, CapsLock, Backspace và các phímkeypress khác không gõ thứ gì đó không gây ra sự kiện, nhưng chúng luôn kích hoạt a keydown.
CPHPython

8

Sự kiện onkeypress hoạt động cho tất cả các khóa trừ ALT, CTRL, SHIFT, ESC trong tất cả các trình duyệt trong đó sự kiện onkeydown hoạt động cho tất cả các khóa. Có nghĩa là sự kiện onkeydown nắm bắt tất cả các phím.


nhấn phím cũng bỏ qua xóa, mũi tên, nhà / kết thúc, PGUp / PGDn, xem câu trả lời của tôi để biết chi tiết (bạn cũng có thể muốn cập nhật câu trả lời của mình)
YakovL

4

Chỉ muốn chia sẻ một sự tò mò:

khi sử dụng sự kiện onkeydown để kích hoạt phương thức JS, mã char cho sự kiện đó KHÔNG giống với sự kiện bạn nhận được với onkeypress!

Chẳng hạn, các phím numpad sẽ trả về các mã tương tự như các phím số phía trên các phím chữ cái khi sử dụng onkeypress, nhưng KHÔNG khi sử dụng onkeydown!

Mất vài giây để tìm hiểu lý do tại sao tập lệnh của tôi đã kiểm tra một số mã nhất định không thành công khi sử dụng onkeydown!

Bản trình diễn: https://www.w3schools.com/code/tryit.asp?filename=FMMBXKZLP1MK

và vâng. Tôi biết định nghĩa của các phương thức là khác nhau .. nhưng điều rất khó hiểu là trong cả hai phương thức, kết quả của sự kiện được truy xuất bằng event.keyCode .. nhưng chúng không trả về cùng một giá trị .. không phải là rất thực hiện khai báo.


Dường như mọi thứ đều giống nhau đối với Nhân vật Số ( 0123456789)
Mrigank Pawagi

Và bạn có để ý rằng keyDown cung cấp KEY trên bàn phím không, trong khi keyPress cung cấp chính xác Ký tự mà chúng ta vừa gõ (hoặc nhấp)
Mrigank Pawagi 27/03/18

2

Về cơ bản, các sự kiện này hoạt động khác nhau trên loại và phiên bản trình duyệt khác nhau, tôi đã tạo một thử nghiệm jsBin nhỏ và bạn có thể kiểm tra bảng điều khiển để tìm hiểu xem các sự kiện này hoạt động như thế nào đối với môi trường được nhắm mục tiêu của bạn, hy vọng điều này sẽ giúp ích. http://jsbin.com/zipivadu/10/edit


1

Cập nhật câu trả lời:

KeyDown

  • Bắn nhiều lần khi bạn giữ phím.
  • Bắn khóa meta.

Bàn phím

  • Bắn nhiều lần khi bạn giữ phím.
  • không bắn phím meta.

KeyUp

  • Bắn một lần vào cuối khi bạn nhả phím.
  • Bắn khóa meta.

Đây là hành vi trong cả hai addEventListenerjQuery.

https://jsbin.com/vebaholamu/1/edit?js,console,output <- thử ví dụ

cho thấy ví dụ với việc giữ SSS

(câu trả lời đã được chỉnh sửa với phản hồi chính xác, ảnh chụp màn hình & ví dụ)


Ngoại trừ khóa phím cũng bắn nhiều lần
bluejayke

-1, vì ít nhất một chi tiết về điều này là sai trong ít nhất Chrome; như @bluejayke nói, KeyDown cũng bắn liên tục khi bạn giữ phím.
Đánh dấu Amery

Vâng, các bạn nói đúng, xin lỗi vì sai lầm của tôi; trả lời chỉnh sửa.
Quang Văn

0

Một vài sự kiện thực tế có thể hữu ích để quyết định xử lý sự kiện nào (chạy tập lệnh bên dưới và tập trung vào hộp nhập):

$('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/>

Nhấn:

  • phím chèn không / đánh máy (ví dụ Shift, Ctrl) sẽ không kích hoạt keypress. Nhấn Ctrlvà phát hành nó:

    phím tắt 17 17 Kiểm soát

    keyup 17 17 Kiểm soát

  • phím từ bàn phím mà áp dụng ký tự biến đổi để các nhân vật khác có thể dẫn đến chếttrùng lặp "chìa khóa" (ví dụ ~, ´) trên keydown. Nhấn ´và thả nó để hiển thị gấp đôi ´´:

    keydown 192 192 Chết

    keydown 192 192 ạc

    nhấn phím 180 180

    nhấn phím 180 180

    keyup 192 192 Chết

Ngoài ra, các đầu vào không gõ (ví dụ như ranged <input type="range">) vẫn sẽ kích hoạt tất cả các sự kiện gõ phím, nhấn phím và nhấn phím theo các phím được nhấn.

Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.