.keyCode so với .which


228

Tôi nghĩ rằng điều này sẽ được trả lời ở đâu đó trên Stack Overflow, nhưng tôi không thể tìm thấy nó.

Nếu tôi đang nghe một sự kiện nhấn phím, tôi nên sử dụng .keyCodehoặc .whichđể xác định xem phím Enter đã được nhấn chưa?

Tôi đã luôn luôn làm một cái gì đó như sau:

$("#someid").keypress(function(e) {
  if (e.keyCode === 13) {
    e.preventDefault();
    // do something
  }
});

Nhưng tôi đang thấy các ví dụ sử dụng .whichthay vì .keyCode. Có gì khác biệt? Là một trình duyệt chéo thân thiện hơn so với người khác?


Câu trả lời:


209

Lưu ý: Câu trả lời dưới đây được viết vào năm 2010. Ở đây nhiều năm sau, cả hai keyCodewhichđều không được ủng hộ key(đối với khóa logic) và code(đối với vị trí vật lý của khóa). Nhưng lưu ý rằng IE không hỗ trợ codevà hỗ trợ của nó keydựa trên phiên bản cũ hơn của thông số kỹ thuật nên không hoàn toàn chính xác. Khi tôi viết điều này, Edge hiện tại dựa trên EdgeHTML và Chakra cũng không hỗ trợ code, nhưng Microsoft đang triển khai thay thế dựa trên Blink - và V8 cho Edge, có lẽ là sẽ / sẽ.


Một số trình duyệt sử dụng keyCode, số khác sử dụng which.

Nếu bạn đang sử dụng jQuery, bạn có thể sử dụng một cách đáng tin cậy whichkhi jQuery chuẩn hóa mọi thứ ; Thêm ở đây.

Nếu bạn không sử dụng jQuery, bạn có thể làm điều này:

var key = 'which' in e ? e.which : e.keyCode;

Hay cách khác:

var key = e.which || e.keyCode || 0;

... Xử lý khả năng e.whichcó thể xảy ra 0(bằng cách khôi phục điều đó 0ở cuối, bằng cách sử dụng toán tử mạnh mẽ của JavaScript|| ).


2
Cảm ơn TJ Tôi sẽ tìm tài liệu tham khảo cho việc này ở đâu? Không phải tôi không tin bạn, tôi chỉ tò mò thôi! ... Tôi thấy bạn chỉ cần thêm rằng, cảm ơn. Vì vậy, ngay cả đối với những người không sử dụng jquery ,. Bạn là lựa chọn nào tốt hơn?
ScottE

7
@ScottE: Nếu không sử dụng jQuery, bạn phải tự xử lý việc này một cách rõ ràng. Tôi thường làm như thế này var key = event.which || event.keyCode;Điều đó sẽ sử dụng event.whichnếu nó được xác định và không phải falsey, hoặc event.keyCodenếu whichkhông xác định hoặc falsey. Về mặt kỹ thuật có lẽ tôi nên làm var key = typeof event.which === "undefined" ? event.keyCode : event.which;nhưng nếu event.which0(có thể như vậy 0?), Tôi không thể quan tâm đến những việc tôi làm.
TJ Crowder

2
@ScottE, đây là một tài liệu tham khảo cơ bản: quirksmode.org/js/keys.html (nó không bao gồm which, mà tôi nghĩ chỉ được cung cấp bởi jQuery nhưng tôi không chắc chắn 100%, nhưng nó sẽ giúp bạn bắt đầu nhìn thấy sự khác biệt trong trình duyệt)
Mottie

1
@fudgey: whichđược cung cấp cho keypresstất cả các trình duyệt trừ IE. Và quirksmode không có thẩm quyền ở đây. Để tham khảo, liên kết mà @TJ Crowder đã đăng tốt hơn nhiều: unixpapa.com/js/key.html .
Tim Down

5
@TJ Crowder: Có, whichtài sản của sự kiện có thể bằng 0 và điều này có thể tạo ra sự khác biệt lớn cho hầu hết các ứng dụng. Ví dụ: các khóa không in được trong Firefox có whichthuộc tính bằng 0 và cùng thuộc keyCodetính với keydown. Phím Home có keyCode36 trên PC của tôi trong Firefox, đó là mã ký tự cho "$", điều này khiến cho không thể phân biệt giữa người dùng nhấn phím Home và người dùng nhập ký tự $ bằng cách sử dụng event.which || event.keyCode.
Tim Down

32

jQuery normalises event.whichtuỳ thuộc vào việc event.which, event.keyCodehoặc event.charCodeđược hỗ trợ bởi các trình duyệt:

// Add which for key events
if ( event.which == null && (event.charCode != null || event.keyCode != null) ) {
   event.which = event.charCode != null ? event.charCode : event.keyCode;
}

Một lợi ích bổ sung .whichlà jQuery cũng làm điều đó khi nhấp chuột:

// Add which for click: 1 === left; 2 === middle; 3 === right
// Note: button is not normalized, so don't use it
if ( !event.which && event.button !== undefined ) {
    event.which = (event.button & 1 ? 1 : ( event.button & 2 ? 3 : ( event.button & 4 ? 2 : 0 ) ));
}

2
var key = event.which || event.charCode || event.keyCode
Anne van Rossum

@ anne-van-rossum, chỉ event.wich == null && ...kiểm tra null hoặc không xác định. bạn event.wich || ...thử nghiệm cho falsy (undefined, null, false, 0, '', vv)
aMarCruz

@aMarCruz Falsy về mục đích. Ví dụ: bug.webkit.org/show_orms.cgi?id=16735 với báo cáo Webkit 0. Và tôi không nghĩ rằng việc kiểm tra ""hay []làm tổn thương.
Anne van Rossum

20

Nếu bạn đang ở trong vanilla Javascript, xin lưu ý keyCode hiện không được dùng nữa và sẽ bị loại bỏ:

Tính năng này đã bị xóa khỏi các tiêu chuẩn Web. Mặc dù một số trình duyệt vẫn có thể hỗ trợ nó, nhưng nó đang trong quá trình bị loại bỏ. Tránh sử dụng nó và cập nhật mã hiện có nếu có thể; xem bảng tương thích ở dưới cùng của trang này để hướng dẫn quyết định của bạn. Xin lưu ý rằng tính năng này có thể ngừng hoạt động bất cứ lúc nào

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

Thay vào đó, hãy sử dụng: .key hoặc .code tùy thuộc vào hành vi bạn muốn: https://developer.mozilla.org/en-US/docs/Web/API/PalEvent/code https://developer.mozilla.org/en -US / docs / Web / API / KeyboardEvent / key

Cả hai đều được thực hiện trên các trình duyệt hiện đại.


.code tương ứng với vị trí vật lý của phím trên bàn phím trong khi .key tương ứng với ký tự được tạo bởi phím được nhấn bất kể vị trí.
Christopher

1
Cả 'mã' và 'khóa' đều có các đặc điểm trong các trình duyệt hiện đại. Sử dụng ví dụ "Dùng thử" trên MDN developer.mozilla.org/en-US/docs/Web/API/PalEvent/code trong các trình duyệt khác nhau cho thấy IE11 / IE Edge không triển khai 'mã' và 'khóa' việc triển khai không khớp với việc triển khai trong Chrome / FF / Safari (sự khác biệt chủ yếu xuất hiện ở các ký tự điều khiển như Escape và Enter). Tôi nghĩ rằng việc sử dụng một thư viện có thể là dễ dàng nhất trừ khi bạn sẵn sàng tính đến những điều mơ hồ này. Tôi thực sự muốn đây là câu trả lời, nhưng IE vặn cái này lên :-(
Akrikos

Hmm ... thực sự nó không quá tệ để thực hiện khóa theo cách trình duyệt chéo. Các khóa chữ và số thông thường chỉ trả về giá trị của chúng và cho các phím điều khiển (thoát, nhập, tab, v.v.) xuất hiện giống hệt nhau trong hầu hết các trình duyệt ngoại trừ IE11 / Edge thực hiện phiên bản cũ hơn của thông số kỹ thuật, vì vậy ít nhất chỉ có hai giá trị có thể có cho mỗi Chìa khóa.
Akrikos

Tôi sẽ tư vấn sử dụng keythay vì code. Ví dụ: nếu bạn có bàn phím có các phím điều khiển phương tiện, hãy nhấn Phát / Tạm dừng đầu ra "MediaPlayPause" cho keyvà "" cho code.
thdoan

6

nhìn vào đây: https://developer.mozilla.org/en-US/docs/Web/API/event.keyCode

Trong một sự kiện nhấn phím, giá trị Unicode của phím được nhấn được lưu trữ trong thuộc tính keyCode hoặc charCode, không bao giờ cả hai. Nếu phím được nhấn tạo ra một ký tự (ví dụ 'a'), charCode được đặt thành mã của ký tự đó, tôn trọng trường hợp chữ cái. (tức là charCode có tính đến việc phím shift có được giữ không). Mặt khác, mã của phím được nhấn được lưu trong keyCode. keyCode luôn được đặt trong các sự kiện keydown và keyup. Trong những trường hợp này, charCode không bao giờ được đặt. Để lấy mã của khóa bất kể nó được lưu trữ trong keyCode hay charCode, hãy truy vấn thuộc tính nào. Các ký tự được nhập thông qua IME không đăng ký thông qua keyCode hoặc charCode.


6

Tôi muốn giới thiệu event.keyhiện tại. Tài liệu MDN: https://developer.mozilla.org/en-US/docs/Web/API/PalEvent/key

event.KeyCodeevent.whichcả hai đều có những cảnh báo không được chấp nhận ở đầu trang MDN của họ:
https://developer.mozilla.org/en-US/docs/Web/API/PalEvent/keyCode https://developer.mozilla.org/en-US / docs / Web / API / KeyboardEvent / which

Đối với các khóa chữ và số, event.keydường như được triển khai giống hệt nhau trên tất cả các trình duyệt. Đối với các phím điều khiển (tab, enter, esc, v.v.), event.keycó cùng giá trị trên Chrome / FF / Safari / Opera nhưng giá trị khác trong IE10 / 11 / Edge (IE rõ ràng sử dụng phiên bản cũ hơn của thông số kỹ thuật nhưng khớp với nhau như ngày 14 tháng 1 năm 2018).

Đối với các phím chữ và số, một kiểm tra sẽ trông giống như:

event.key === 'a'

Đối với các nhân vật điều khiển, bạn cần phải làm một cái gì đó như:

event.key === 'Esc' || event.key === 'Escape'

Tôi đã sử dụng ví dụ ở đây để kiểm tra trên nhiều trình duyệt (tôi phải mở bằng codepen và chỉnh sửa để làm cho nó hoạt động với IE10): https://developer.mozilla.org/en-US/docs/Web/API/PalEvent/ mã

event.code được đề cập trong một câu trả lời khác như một khả năng, nhưng IE10 / 11 / Edge không thực hiện nó, vì vậy, nếu bạn muốn hỗ trợ IE.


2

Một thư viện Javascript mạnh mẽ để chụp đầu vào bàn phím và các tổ hợp phím được nhập. Nó không có phụ thuộc.

http://jaywcjlove.github.io/hotkeys/

hotkeys('ctrl+a,ctrl+b,r,f', function(event,handler){
    switch(handler.key){
        case "ctrl+a":alert('you pressed ctrl+a!');break;
        case "ctrl+b":alert('you pressed ctrl+b!');break;
        case "r":alert('you pressed r!');break;
        case "f":alert('you pressed f!');break;
    }
});

hotkeys hiểu được bổ như sau: , shift, option, , alt, ctrl, control, command, và .

Các phím đặc biệt sau đây có thể được sử dụng cho các phím tắt: backspace, tab, clear, enter, return, esc, escape, space, up, down, left, right, home, end, pageup, pagedown, del, deletef1thông qua f19.


Mặc dù vậy, nó không có Array.prototype.indexOf, vì vậy nếu bạn đang sử dụng cái này trong một thư viện khác, nó có thể không phù hợp vì nó sửa đổi phạm vi toàn cầu. Nó cũng xuất hiện để sử dụng không dùng nữa event.keyCode.
Akrikos

Thư viện này không phát hiện ra Fn trên máy tính xách tay Vaio của tôi.
thdoan

0

Trong Firefox, thuộc tính keyCode không hoạt động trên sự kiện onkeypress (sẽ chỉ trả về 0). Đối với giải pháp trình duyệt chéo, hãy sử dụng thuộc tính cùng với keyCode, ví dụ:

var x = event.which || event.keyCode;  // Use either which or keyCode, depending on browser support
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.