KeyboardEvent.keyCode không được dùng nữa. Điều này có ý nghĩa gì trong thực tế?


92

Theo MDN, chúng ta chắc chắn không nên sử dụng.keyCode tài sản này. Nó không được dùng nữa:

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

Trên trường W3, thông tin này được đưa ra và chỉ có một lưu ý phụ nói rằng chỉ .keyCodeđược cung cấp để tương thích và phiên bản mới nhất của Đặc tả sự kiện DOM khuyên bạn nên sử dụng.key tính thay thế.

Vấn đề là .keykhông được hỗ trợ bởi các trình duyệt, vì vậy chúng ta nên sử dụng những gì? Có điều gì tôi đang thiếu?


Câu trả lời:


32

Bạn có ba cách để xử lý, vì nó được viết trên liên kết bạn đã chia sẻ.

if (event.key !== undefined) {

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

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

}

bạn nên xem xét chúng, đó là cách đúng nếu bạn muốn hỗ trợ nhiều trình duyệt.

Nó có thể dễ dàng hơn nếu bạn thực hiện một cái gì đó như thế này.

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);
};

13
Tôi đã đọc điều đó nhưng có vẻ như có rất nhiều mã bổ sung không vì lý do gì khác ngoài việc MDN cho biết có thứ gì đó không được dùng nữa, khi nó thực sự hoạt động tốt trên tất cả các trình duyệt chính. Nhưng nếu đó là cách chính xác thì cảm ơn!
Jason210

3
Wow nhìn một cái này. caniuse.com/#search=keyCode (Thuộc tính KeyboardEvent này được hỗ trợ hiệu quả trong tất cả các trình duyệt (kể từ IE6 +, Firefox 2+, Chrome 1+, v.v. "nói về .keyCode)
Miguel Lattuada

2
Đó là những gì rất khó chịu về tất cả những điều này. Tất cả các trình duyệt chính đều hỗ trợ keyCode, nhưng hãy thử kiểm tra thuộc tính .key, đây là thuộc tính được khuyến nghị và hầu như không sử dụng nó!
Jason210

4
Vâng, chúng tôi đã đến cuối tháng 5 năm 2016 và chrome cuối cùng đã triển khai thuộc tính KeyboardEvent.key. Safari cùng với mọi trình duyệt di động vẫn chưa tham gia vào bữa tiệc "16,5% tổng số người dùng". Ngoài ra, đáng buồn là Microsoft Edge và Gecko mã hóa khá nhiều sự kiện khác nhau, ví dụ: sự kiện quan trọng cho mũi tên lên được mã hóa thành "Lên" thay vì "ArrowUp".
Joshua Dawson

Tôi nghĩ điều này sẽ giúp bạn stackoverflow.com/questions/41465542/…
Maven97

26

Bên cạnh đó tất cả các keyCode , , charCodekeyIdentifier được chấp nhận:
charCodekeyIdentifiernhững tính năng phi tiêu chuẩn.
keyIdentifierbị xóa kể từ Chrome 54 và Opera 41.0
keyCodetrả về 0, trong sự kiện nhấn phím với các ký tự bình thường trên FF.

Thuộc tính chính :

 readonly attribute DOMString key

Giữ một giá trị thuộc tính khóa tương ứng với phím được nhấn

Tính đến thời điểm viết bài này, thuộc keytính được hỗ trợ bởi tất cả các trình duyệt chính như: Firefox 52, Chrome 55, Safari 10.1, Opera 46. Ngoại trừ Internet Explorer 11 có: mã nhận dạng khóa không chuẩn và hoạt động không chính xác với AltGraph. Thêm thông tin
Nếu điều đó quan trọng và / hoặc khả năng tương thích ngược, thì bạn có thể sử dụng tính năng phát hiện như trong đoạn mã sau:

Lưu ý rằng keygiá trị khác với keyCodehoặc whichthuộc tính ở chỗ: nó chứa tên của khóa chứ không phải mã của nó. Nếu chương trình của bạn cần mã ký tự thì bạn có thể sử dụng charCodeAt(). Đối với các ký tự có thể in đơn lẻ, bạn có thể sử dụng charCodeAt(), nếu bạn đang xử lý các khóa có giá trị chứa nhiều ký tự như ArrowUp cơ hội: bạn đang kiểm tra các khóa đặc biệt và thực hiện các hành động tương ứng. Vì vậy, cố gắng thực hiện một bảng giá trị phím và mã tương ứng của họ charCodeArr["ArrowUp"]=38, charCodeArr["Enter"]=13, charCodeArr[Escape]=27... và như vậy, xin vui lòng hãy nhìn vào giá trị chính và họ mã tương ứng

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

Có thể bạn muốn xem xét khả năng tương thích chuyển tiếp, tức là sử dụng các thuộc tính kế thừa khi chúng có sẵn và chỉ khi bị loại bỏ, hãy chuyển sang các thuộc tính mới:

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

Xem thêm: KeyboardEvent.codetài liệu về tài sản và một số chi tiết khác trong câu trả lời này .


Giải pháp của bạn không hoạt động trong trình duyệt của tôi (Windows 10, Chrome 60, bàn phím Bỉ). Trước hết, charCodeArrchức năng không tồn tại. Ngoài ra, charCodeAtkhông hoạt động cho tất cả các giá trị của e.key. Ví dụ: đối với khóa Enter/ Return, giá trị của thuộc e.keytính là "Enter"và việc thực thi charCodeArrcho chuỗi đó sẽ trả về giá trị 69(là mã ASCII cho ký tự E).
John Slegers,

@JohnSlegers, vâng, đó là lỗi đánh máy, ý tôi là một mảng do người dùng tạo. Vui lòng xem câu trả lời cập nhật của tôi để biết thêm chi tiết.
user10089632

19

TLDR: Tôi khuyên bạn nên nên sử dụng các thuộc tính event.keyvà mới event.codethay vì các thuộc tính cũ. IE và Edge có hỗ trợ các thuộc tính này, nhưng chưa hỗ trợ các tên khóa mới. Đối với họ, có một polyfill nhỏ làm cho họ xuất ra các tên mã / khóa tiêu chuẩn:

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


Tôi đến với câu hỏi này để tìm kiếm lý do của cảnh báo MDN giống như OP. Sau khi tìm kiếm thêm, vấn đề keyCodetrở nên rõ ràng hơn:

Vấn đề khi sử dụng keyCodelà các bàn phím không phải tiếng Anh có thể tạo ra các kết quả đầu ra khác nhau và ngay cả các bàn phím có bố cục khác nhau cũng có thể tạo ra kết quả không nhất quán. Thêm vào đó, có trường hợp của

Nếu bạn đọc thông số kỹ thuật của W3C: https://www.w3.org/TR/uievents/#interface-keyboardevent

Trên thực tế, keyCode và charCode không nhất quán giữa các nền tảng và thậm chí việc triển khai giống nhau trên các hệ điều hành khác nhau hoặc sử dụng các bản địa hóa khác nhau.

Nó đi sâu vào một số mô tả những gì đã xảy ra với keyCode: https://www.w3.org/TR/uievents/#legacy-key-attributes

Các tính năng này chưa bao giờ được chỉ định chính thức và việc triển khai trình duyệt hiện tại khác nhau theo những cách đáng kể. Số lượng lớn nội dung kế thừa, bao gồm cả thư viện tập lệnh, dựa vào việc phát hiện tác nhân người dùng và hành động tương ứng có nghĩa là bất kỳ nỗ lực nào để chính thức hóa các thuộc tính và sự kiện kế thừa này sẽ có nguy cơ phá vỡ nhiều nội dung mà nó sẽ sửa hoặc bật. Ngoài ra, các thuộc tính này không phù hợp với việc sử dụng quốc tế, cũng như không giải quyết các vấn đề về khả năng tiếp cận.

Vì vậy, sau khi xác định lý do tại sao Mã khóa kế thừa bị thay thế, hãy xem những gì bạn cần làm hôm nay:

  1. Tất cả các trình duyệt hiện đại đều hỗ trợ các thuộc tính mới (keycode).
  2. IE và Edge hỗ trợ phiên bản cũ hơn của thông số kỹ thuật, có các tên khác nhau cho một số phím. Bạn có thể sử dụng miếng dán cho nó: https://github.com/shvaikalesh/shim-keyboard-event-key (hoặc cuộn của riêng bạn - dù sao nó cũng khá nhỏ)
  3. Edge đã sửa lỗi này trong bản phát hành mới nhất (có thể sẽ được phát hành vào tháng 4 năm 2018) - https://developer.microsoft.com/en-us/microsoft-edge/platform/issues/8860571/
  4. Tham khảo danh sách các khóa sự kiện bạn có thể sử dụng: https://www.w3.org/TR/uievents-key/

Theo MDN , cả Internet Explorer và Edge đều không hỗ trợKeyboardEvent.code. Ngoài ra, các giá trị chokeycodephụ thuộc vào trình duyệt. Cả hai vấn đề tạo rakeycodekhông thực tế để sử dụng trong các ứng dụng thực tế.
John Slegers


Nếu tôi muốn kiểm tra các phím mũi tên, trang lên / xuống, trang chủ và kết thúc, tôi nên sử dụng keyhay code? Nó thường là một phím vật lý, nhưng cũng có thể phụ thuộc vào Num Lock và bố cục ... Cách tốt nhất là gì?
Jake

12

MDN đã cung cấp một giải pháp:

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

3
Thật không may, keygiá trị chuỗi dành riêng cho trình duyệt giống như "Enter"hoặc "ArrowUp"và không có cách chuẩn hóa nào để chuyển đổi nó thành mã tương ứng. vì vậy bạn sẽ cần thêm mã soạn sẵn để chuyển đổi giữa khóa và mã.
John Slegers,

6

Ví dụ: nếu bạn muốn phát hiện xem phím "Enter" đã được nhấp hay chưa:

Thay vì

event.keyCode === 13

Làm nó thích

event.key === 'Enter'
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.