Hôm nay cafedev chia sẻ về bàn phím khi làm việc với Javascript. Trước khi sử dụng bàn phím, xin lưu ý rằng trên các thiết bị hiện đại có nhiều cách khác để “nhập nội dung”. Ví dụ: mọi người sử dụng nhận dạng giọng nói (đặc biệt là trên thiết bị di động) hoặc sao chép / dán bằng chuột.

Vì vậy, nếu chúng ta muốn theo dõi bất kỳ đầu vào nào vào một trường <input>, thì các sự kiện bàn phím là không đủ. Có một sự kiện khác được đặt tên input để theo dõi các thay đổi của một trường <input>, bằng mọi cách. Và nó có thể là một lựa chọn tốt hơn cho nhiệm vụ như vậy. Chúng ta sẽ trình bày ở phần sau của chương Sự kiện: thay đổi, nhập, cắt, sao chép, dán .

Các sự kiện bàn phím nên được sử dụng khi chúng ta muốn xử lý các thao tác trên bàn phím (bàn phím ảo cũng được tính). Ví dụ: để phản ứng trên các phím mũi tên Up và Down hoặc phím nóng (bao gồm các tổ hợp phím).

1. Keydown and keyup

Các sự kiện keydown xảy ra khi một phím được nhấn xuống và sau đó keyup – khi nó được nhả ra.

1.1. event.code và event.key

Các thuộc tính key của đối tượng sự kiện cho phép để có được những ký tự, trong khi thuộc tính code của đối tượng sự kiện cho phép để có được “code key”.

Ví dụ, Z có thể nhấn cùng một phím có hoặc không Shift. Điều đó cho chúng ta hai ký tự khác nhau: chữ thường z và chữ hoa Z.

Các event.key chính xác là ký tự, và nó sẽ khác nhau. Nhưng event.code giống nhau:

Chìa khóaevent.keyevent.code
Zz (chữ thường)KeyZ
Shift+ZZ (chữ hoa)KeyZ

Nếu người dùng làm việc với các ngôn ngữ khác nhau, thì việc chuyển sang ngôn ngữ khác sẽ tạo ra một ký tự hoàn toàn khác thay vì “Z”. Điều đó sẽ trở thành giá trị của event.key, trong khi event.code luôn luôn là như nhau: “KeyZ”.

“KeyZ” và các mã khóa khác

Mỗi phím đều có code phụ thuộc vào vị trí của nó trên bàn phím. Các code chính được mô tả trong đặc tả mã Sự kiện giao diện người dùng .

Ví dụ:

  • Phím chữ có code  “Key<letter>”: “KeyA”, “KeyB”, vv
  • Các khóa chữ số có mã “Digit<number>”:: “Digit0”, “Digit1″v.v.
  • Các phím đặc biệt được code hoá bằng tên của họ: “Enter”, “Backspace”, “Tab”, vv

Có một số bố cục bàn phím phổ biến và đặc điểm kỹ thuật cung cấp mã phím cho từng loại trong số chúng.

Đọc phần chữ và số của thông số kỹ thuật để biết thêm mã 

Vấn đề trường hợp:, “KeyZ” và không “keyZ”

Có vẻ hiển nhiên, nhưng người ta vẫn mắc sai lầm.

Hãy tránh các kiểu nhầm lẫn: nó là KeyZ, không phải keyZ. Kiểm tra như event.code==”keyZ” sẽ không hoạt động: chữ cái đầu tiên của “Key” phải là chữ hoa.

Điều gì xảy ra nếu một khóa không cung cấp bất kỳ ký tự nào? Ví dụ, Shift hoặc F1 hoặc những phím  khác. Đối với các khóa đó, event.key gần giống như event.code:

Chìa khóaevent.keyevent.code
F1F1F1
BackspaceBackspaceBackspace
ShiftShiftShiftRight hoặc là ShiftLeft

Xin lưu ý rằng event.code chỉ định chính xác phím nào được nhấn. Ví dụ, hầu hết các bàn phím đều có hai phím Shift: ở bên trái và ở bên phải. Các event.code cho chúng ta biết chính xác ai bị nhấn, và event.key chịu trách nhiệm về “ý nghĩa” của khóa: nó là (một “Shift”).

Giả sử, chúng ta muốn xử lý một phím nóng: (hoặc cho Mac). Hầu hết các trình soạn thảo văn bản đều gắn hành động “Hoàn tác” trên đó. Chúng ta có thể bật chế độ nghe và kiểm tra phím nào được nhấn.Ctrl+Z Cmd+Z keydown

Có một tình huống khó xử ở đây: trong một người nghe như vậy, chúng ta nên kiểm tra giá trị của event.key hoặc event.code?

Một mặt, giá trị của event.key là một ký tự, nó thay đổi tùy thuộc vào ngôn ngữ. Nếu khách truy cập có một số ngôn ngữ trong Hệ điều hành và chuyển đổi giữa chúng, thì cùng một phím sẽ cung cấp các ký tự khác nhau. Vì vậy, nó là hợp lý để kiểm tra event.code, nó luôn luôn giống nhau.

Như thế này:

document.addEventListener('keydown', function(event) {
  if (event.code == 'KeyZ' && (event.ctrlKey || event.metaKey)) {
    alert('Undo!')
  }
});

Mặt khác, có một vấn đề với event.code. Đối với các bố cục bàn phím khác nhau, cùng một phím có thể có các ký tự khác nhau.

Ví dụ, đây là bố cục của Hoa Kỳ (“QWERTY”) và bố cục của Đức (“QWERTZ”) (từ Wikipedia):

Đối với cùng một phím, bố cục của Hoa Kỳ có “Z”, trong khi bố cục của Đức có “Y” (các chữ cái được hoán đổi).

Theo nghĩa đen, event.code sẽ giống KeyZ đối với những người có bố cục tiếng Đức khi họ nhấn Y.

Nếu chúng ta kiểm tra event.code == ‘KeyZ’, thì đối với những người có bố cục tiếng Đức, bài kiểm tra đó sẽ vượt qua khi họ nhấn Y.

Điều đó nghe thực sự kỳ lạ, nhưng nó là như vậy. Đặc điểm kỹ thuật đề cập rõ ràng hành vi như vậy.

Vì vậy, event.code có thể khớp một ký tự sai cho bố cục không mong muốn. Các chữ cái giống nhau trong các bố cục khác nhau có thể ánh xạ đến các phím vật lý khác nhau, dẫn đến các code khác nhau. May mắn thay, điều đó chỉ xảy ra với một số code, ví dụ như keyA, keyQ, keyZ(như chúng ta đã nhìn thấy), và không xảy ra với các phím đặc biệt như Shift. Bạn có thể tìm thấy danh sách trong thông số kỹ thuật .

Để theo dõi các ký tự phụ thuộc vào bố cục một cách đáng tin cậy, event.key có thể là một cách tốt hơn.

Mặt khác, event.code có lợi ích là luôn giữ nguyên, ràng buộc với vị trí chính thực, ngay cả khi khách truy cập thay đổi ngôn ngữ. Vì vậy, các phím nóng dựa vào nó hoạt động tốt ngay cả trong trường hợp chuyển đổi ngôn ngữ.

Chúng ta có muốn xử lý các khóa phụ thuộc vào bố cục không? Sau đó event.key là con đường dễ đi.

Hay chúng ta muốn một phím nóng hoạt động ngay cả sau khi chuyển đổi ngôn ngữ? Sau đó, event.code có thể tốt hơn.

2. Tự động lặp lại

Nếu một phím được nhấn trong một thời gian đủ lâu, phím đó sẽ bắt đầu “tự động lặp lại”: các phím keydown này sẽ kích hoạt lặp đi lặp lại, và sau đó khi nó được nhả ra, chúng ta cuối cùng cũng nhận được keyup. Vì vậy, việc có nhiều keydown và duy nhất là chuyện bình thường keyup.

Đối với các sự kiện được kích hoạt bằng cách tự động lặp lại, đối tượng sự kiện có thuộc tính event.repeat được đặt thành true.

3. Các hành động mặc định

Các hành động mặc định khác nhau, vì bàn phím có thể thực hiện nhiều thao tác khác nhau.

Ví dụ:

  • Một ký tự xuất hiện trên màn hình (kết quả rõ ràng nhất).
  • Một ký tự bị xóa ( phím Delete).
  • Trang được cuộn ( phím PageDown).
  • Trình duyệt mở hộp thoại “Lưu trang” ( )Ctrl+S
  • …và như thế.

Việc ngăn chặn hành động mặc định trên keydown có thể hủy hầu hết chúng, ngoại trừ các khóa đặc biệt dựa trên hệ điều hành. Ví dụ: trên Windows đóng cửa sổ trình duyệt hiện tại. Và không có cách nào để ngăn chặn nó bằng cách ngăn hành động mặc định trong JavaScript.Alt+F4

Ví dụ, <input> dưới đây hy vọng một số điện thoại, vì vậy nó không chấp nhận các phím trừ chữ số, +, ()hoặc -:

<!--
Cafedev.vn - Kênh thông tin IT hàng đầu Việt Nam
@author cafedevn
Contact: cafedevn@gmail.com
Fanpage: https://www.facebook.com/cafedevn
Group: https://www.facebook.com/groups/cafedev.vn/
Instagram: https://instagram.com/cafedevn
Twitter: https://twitter.com/CafedeVn
Linkedin: https://www.linkedin.com/in/cafe-dev-407054199/
Pinterest: https://www.pinterest.com/cafedevvn/
YouTube: https://www.youtube.com/channel/UCE7zpY_SlHGEgo67pHxqIoA/
-->

<script>
function checkPhoneKey(key) {
  return (key >= '0' && key <= '9') || key == '+' || key == '(' || key == ')' || key == '-';
}
</script>
<input onkeydown="return checkPhoneKey(event.key)" placeholder="Phone, please" type="tel">

Xin lưu ý rằng các phím đặc biệt, chẳng hạn như Backspace, Left, Right, , không làm việc trong các input. Đó là một tác dụng phụ của bộ lọc nghiêm ngặt .Ctrl+V

Hãy thư giãn nó một chút:

<script>
function checkPhoneKey(key) {
  return (key >= '0' && key <= '9') || key == '+' || key == '(' || key == ')' || key == '-' ||
    key == 'ArrowLeft' || key == 'ArrowRight' || key == 'Delete' || key == 'Backspace';
}
</script>
<input onkeydown="return checkPhoneKey(event.key)" placeholder="Phone, please" type="tel">

Giờ đây, mũi tên và tính năng xóa hoạt động tốt.

… Nhưng chúng ta vẫn có thể nhập bất cứ thứ gì bằng cách sử dụng chuột và nhấp chuột phải vào + Dán. Vì vậy bộ lọc không đáng tin cậy 100%. Chúng ta có thể để nó như vậy, bởi vì hầu hết thời gian nó hoạt động. Hoặc một cách tiếp cận khác sẽ là theo dõi sự kiện input – nó sẽ kích hoạt sau bất kỳ sửa đổi nào. Ở đó, chúng ta có thể kiểm tra giá trị mới và đánh dấu / sửa đổi nó khi nó không hợp lệ.

4. Di sản

Trong quá khứ, đã có một sự kiện keypress, và cũng có thể thuộc tính keyCode, charCode, which của đối tượng sự kiện.

Có rất nhiều điểm không tương thích của trình duyệt khi làm việc với chúng, đến nỗi các nhà phát triển đặc điểm kỹ thuật không có cách nào khác ngoài việc ngừng sử dụng tất cả chúng và tạo các sự kiện mới, hiện đại (được mô tả ở trên trong chương này). Mã cũ vẫn hoạt động, vì các trình duyệt tiếp tục hỗ trợ chúng, nhưng hoàn toàn không cần sử dụng chúng nữa.

5. Tóm lược

Nhấn một phím luôn tạo ra một sự kiện bàn phím, có thể là chìa khóa biểu tượng hoặc các phím đặc biệt như Shift hay Ctrl và vân vân. Ngoại lệ duy nhất là phím Fn đôi khi xuất hiện trên bàn phím máy tính xách tay. Không có sự kiện bàn phím cho nó, vì nó thường được triển khai ở cấp thấp hơn OS.

Sự kiện bàn phím:

  • keydown – khi nhấn phím (tự động lặp lại nếu nhấn phím lâu),
  • keyup – khi thả chìa khóa.

Thuộc tính sự kiện bàn phím chính:

  • code – “mã phím” ( “KeyA”, “ArrowLeft”v.v.), cụ thể cho vị trí thực của phím trên bàn phím.
  • key- ký tự ( “A”, “a”v.v.), đối với các khóa không phải ký tự, chẳng hạn Esc, thường có cùng giá trị như code.

Trước đây, các sự kiện bàn phím đôi khi được sử dụng để theo dõi thông tin nhập của người dùng trong các trường biểu mẫu. Điều đó không đáng tin cậy, vì đầu vào có thể đến từ nhiều nguồn khác nhau. Chúng ta có input và change các sự kiện để xử lý bất kỳ đầu vào nào (được đề cập ở phần sau của chương Sự kiện: thay đổi, nhập, cắt, sao chép, dán ). Chúng kích hoạt sau bất kỳ loại đầu vào nào, bao gồm sao chép dán hoặc nhận dạng giọng nói.

Chúng ta nên sử dụng các sự kiện bàn phím khi chúng ta thực sự muốn có bàn phím. Ví dụ: để phản ứng trên phím nóng hoặc phím đặc biệt.

Nguồn và tài liệu tiếng anh tham khảo:

Full series tự học Javascript từ cơ bản tới nâng cao tại đây nha.

Nếu bạn thấy hay và hữu ích, bạn có thể tham gia các kênh sau của cafedev để nhận được nhiều hơn nữa:

Chào thân ái và quyết thắng!

Đăng ký kênh youtube để ủng hộ Cafedev nha các bạn, Thanks you!