KeyboardEvent.keyCode เลิกใช้แล้ว หมายความว่าอย่างไรในทางปฏิบัติ?


114

ตาม MDN เราควรจะแน่นอนที่สุดไม่ได้นำมาใช้.keyCodeสถานที่ให้บริการ เลิกใช้แล้ว:

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

ในโรงเรียน W3 ข้อเท็จจริงนี้ถูกเล่นลงและมีเพียงข้อความด้านข้างที่ระบุว่า.keyCodeมีไว้เพื่อความเข้ากันได้เท่านั้นและเวอร์ชันล่าสุดของข้อกำหนดเหตุการณ์ DOM แนะนำให้ใช้.keyคุณสมบัติแทน

ปัญหาคือ.keyเบราว์เซอร์ไม่รองรับแล้วเราจะใช้อะไรดีล่ะ? มีบางอย่างที่ฉันขาดหายไป?


3
.keyได้รับการสนับสนุนในผู้พัฒนา
mozilla.org/en-US/docs/Web/API/KeyboardEvent/…

คำตอบ:


39

คุณมีสามวิธีในการจัดการดังที่เขียนไว้ในลิงก์ที่คุณแชร์

if (event.key !== undefined) {

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

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

}

คุณควรพิจารณาพวกเขานั่นเป็นวิธีที่ถูกต้องหากคุณต้องการการสนับสนุนข้ามเบราว์เซอร์

อาจจะง่ายกว่าถ้าคุณใช้สิ่งนี้

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

16
ฉันอ่านแล้ว แต่ดูเหมือนว่าจะมีโค้ดพิเศษจำนวนมากโดยไม่มีเหตุผลอื่นใดนอกจาก MDN ได้กล่าวว่ามีบางอย่างที่เลิกใช้แล้วเมื่อมันทำงานได้ดีในเบราว์เซอร์หลักทั้งหมด แต่ถ้าเป็นวิธีที่ถูกต้องขอบคุณ!
Jason210

3
ว้าวดูนี่สิ caniuse.com/#search=keyCode (คุณสมบัติ KeyboardEvent นี้ได้รับการสนับสนุนในทุกเบราว์เซอร์อย่างมีประสิทธิภาพ (ตั้งแต่ IE6 +, Firefox 2+, Chrome 1+ ฯลฯ "พูดถึง. keyCode)
Miguel Lattuada

3
นั่นคือสิ่งที่น่ารำคาญมากเกี่ยวกับทั้งหมดนี้ เบราว์เซอร์หลักทั้งหมดรองรับ keyCode แต่ลองตรวจสอบคุณสมบัติ. key ซึ่งเป็นคุณสมบัติที่แนะนำและแทบจะไม่ได้ใช้เลย!
Jason210

4
ใช่แล้วเราอยู่ในช่วงปลายเดือนพฤษภาคม 2016 และในที่สุด chrome ก็นำคุณสมบัติ KeyboardEvent.key มาใช้ Safari ร่วมกับเบราว์เซอร์มือถือทุกตัวยังไม่ได้เข้าร่วมปาร์ตี้ "16.5% ของผู้ใช้ทั้งหมด" นอกจากนี้น่าเศร้าที่ Microsoft Edge และ Gecko เข้ารหัสเหตุการณ์บางอย่างแตกต่างกันไปตัวอย่างเช่นเหตุการณ์สำคัญสำหรับลูกศรขึ้นถูกเข้ารหัสเป็น "ขึ้น" แทนที่จะเป็น "ArrowUp"
Joshua Dawson

2
แต่event.keyเป็นสตริงในขณะที่event.keyCodeตัวเลขใช่ไหม? เนื่องจากพวกเขาไม่มีประเภทเดียวกันพวกเขาสามารถมีความหมายเดียวกันได้หรือไม่? หรือคุณหมายถึงevent.code?
bluenote10

28

นอกจากว่าทุกkeyCode , ซึ่ง , charCodeและkeyIdentifierจะเลิกใช้:
charCodeและkeyIdentifierมีคุณสมบัติที่ไม่ได้มาตรฐาน
keyIdentifierจะถูกลบออกเมื่อ Chrome 54 และ Opera 41.0
keyCodeจะคืนค่า 0 ในเหตุการณ์การกดแป้นพิมพ์ที่มีอักขระปกติบน FF

คุณสมบัติหลัก :

 readonly attribute DOMString key

เก็บค่าแอตทริบิวต์ของคีย์ที่สอดคล้องกับคีย์ที่กด

ในขณะที่เขียนนี้keyคุณสมบัตินี้ได้รับการสนับสนุนโดยเบราว์เซอร์หลักทั้งหมดตั้งแต่: Firefox 52, Chrome 55, Safari 10.1, Opera 46 ยกเว้น Internet Explorer 11 ซึ่งมี: ตัวระบุคีย์ที่ไม่ได้มาตรฐานและพฤติกรรมที่ไม่ถูกต้องกับ AltGraph ข้อมูลเพิ่มเติม
หากสิ่งนี้มีความสำคัญและ / หรือความเข้ากันได้แบบย้อนหลังคุณสามารถใช้การตรวจหาคุณสมบัติตามรหัสต่อไปนี้:

สังเกตว่าkeyค่าจะแตกต่างจากkeyCodeหรือwhichคุณสมบัติในนั้น: มีชื่อของคีย์ไม่ใช่รหัส หากโปรแกรมของคุณต้องการรหัสอักขระคุณสามารถใช้ประโยชน์จากcharCodeAt()ไฟล์. สำหรับอักขระที่พิมพ์ได้ตัวเดียวคุณสามารถใช้ได้charCodeAt()หากคุณกำลังจัดการกับคีย์ที่มีค่าหลายอักขระเช่นArrowUp มีโอกาส: คุณกำลังทดสอบคีย์พิเศษและดำเนินการตามนั้น จึงพยายามดำเนินตารางค่าคีย์และรหัสที่สอดคล้องกันของพวกเขาcharCodeArr["ArrowUp"]=38, charCodeArr["Enter"]=13, charCodeArr[Escape]=27... และอื่น ๆ โปรดดูที่ค่าคีย์ของพวกเขาและรหัสที่สอดคล้องกัน

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

คุณอาจต้องการพิจารณาความเข้ากันได้ไปข้างหน้าเช่นใช้คุณสมบัติเดิมในขณะที่พร้อมใช้งานและเมื่อเปลี่ยนไปใช้คุณสมบัติใหม่เท่านั้น:

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

ดูเพิ่มเติม: เอกสารKeyboardEvent.codeคุณสมบัติและรายละเอียดเพิ่มเติมในคำตอบนี้


โซลูชันของคุณใช้ไม่ได้ในเบราว์เซอร์ของฉัน (Windows 10, Chrome 60, แป้นพิมพ์ภาษาเบลเยียม) ก่อนอื่นcharCodeArrไม่มีฟังก์ชันนี้ นอกจากนี้ยังใช้charCodeAtไม่ได้กับค่าทั้งหมดของe.key. ตัวอย่างเช่นสำหรับคีย์Enter/ Returnค่าของe.keyคุณสมบัติคือ"Enter"และการดำเนินการcharCodeArrสำหรับสตริงนั้นจะส่งคืนค่า69(ซึ่งเป็นรหัส ASCII สำหรับอักขระE)
John Slegers

@JohnSlegers ใช่นั่นเป็นการพิมพ์ผิดฉันหมายถึงอาร์เรย์ที่ผู้ใช้สร้างขึ้น โปรดดูคำตอบที่อัปเดตของฉันสำหรับรายละเอียดเพิ่มเติม
user10089632

24

TLDR: ฉันขอแนะนำว่าคุณควรใช้คุณสมบัติใหม่event.keyและevent.codeคุณสมบัติแทนคุณสมบัติเดิม IE และ Edge รองรับคุณสมบัติเหล่านี้ แต่ยังไม่รองรับชื่อคีย์ใหม่ สำหรับพวกเขามีโพลีฟิลล์ขนาดเล็กซึ่งทำให้ส่งออกชื่อคีย์ / รหัสมาตรฐาน:

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


ฉันมาถึงคำถามนี้โดยค้นหาเหตุผลของคำเตือน MDN เดียวกันกับ OP หลังจากค้นหาเพิ่มเติมปัญหาkeyCodeจะชัดเจนยิ่งขึ้น:

ปัญหาในการใช้keyCodeคือแป้นพิมพ์ที่ไม่ใช่ภาษาอังกฤษสามารถให้ผลลัพธ์ที่แตกต่างกันและแม้แต่แป้นพิมพ์ที่มีเค้าโครงต่างกันก็ให้ผลลัพธ์ที่ไม่สอดคล้องกันได้ นอกจากนี้ยังมีกรณีของ

หากคุณอ่านข้อมูลจำเพาะ W3C: https://www.w3.org/TR/uievents/#interface-keyboardevent

ในทางปฏิบัติ keyCode และ charCode ไม่สอดคล้องกันในทุกแพลตฟอร์มและแม้แต่การนำไปใช้งานเดียวกันบนระบบปฏิบัติการที่แตกต่างกันหรือใช้การแปลที่แตกต่างกัน

มีรายละเอียดเชิงลึกเกี่ยวกับสิ่งที่ผิดพลาดkeyCode: https://www.w3.org/TR/uievents/#legacy-key-attributes

คุณลักษณะเหล่านี้ไม่เคยระบุอย่างเป็นทางการและการใช้งานเบราว์เซอร์ในปัจจุบันแตกต่างกันไป เนื้อหาเดิมจำนวนมากรวมถึงไลบรารีสคริปต์ที่อาศัยการตรวจหาตัวแทนผู้ใช้และดำเนินการตามนั้นหมายความว่าความพยายามใด ๆ ที่จะทำให้แอตทริบิวต์และเหตุการณ์ดั้งเดิมเหล่านี้เป็นทางการอาจเสี่ยงต่อการทำลายเนื้อหาได้มากเท่าที่จะแก้ไขหรือเปิดใช้งานได้ นอกจากนี้แอตทริบิวต์เหล่านี้ไม่เหมาะสำหรับการใช้งานระหว่างประเทศและไม่ได้ระบุถึงข้อกังวลเกี่ยวกับการเข้าถึง

ดังนั้นหลังจากกำหนดสาเหตุที่ทำให้รหัสคีย์เดิมถูกแทนที่แล้วเรามาดูสิ่งที่คุณต้องทำในวันนี้:

  1. เบราว์เซอร์ที่ทันสมัยทั้งหมดรองรับคุณสมบัติใหม่ ( keyและcode)
  2. IE และ Edge รองรับข้อมูลจำเพาะเวอร์ชันเก่าซึ่งมีชื่อที่แตกต่างกันสำหรับบางคีย์ คุณสามารถใช้ shim ได้: https://github.com/shvaikalesh/shim-keyboard-event-key (หรือหมุนของคุณเอง - มันค่อนข้างเล็ก แต่อย่างใด)
  3. Edge ได้แก้ไขข้อบกพร่องนี้ในรุ่นล่าสุด (อาจจะออกในเดือนเมษายน 2018) - https://developer.microsoft.com/en-us/microsoft-edge/platform/issues/8860571/
  4. อ้างถึงรายการคีย์เหตุการณ์ที่คุณสามารถใช้ได้: https://www.w3.org/TR/uievents-key/

ตามที่ MDNทั้ง Internet Explorer KeyboardEvent.codeหรือสนับสนุนขอบ นอกจากนี้ค่าสำหรับkeyและcodeขึ้นอยู่กับเบราว์เซอร์ ทั้งปัญหาที่สร้างขึ้นkeyและcodeไม่สามารถใช้งานได้จริงในชีวิตจริง
John Slegers


หากต้องการทดสอบปุ่มลูกศรเลื่อนหน้าขึ้น / ลงหน้าแรกและท้ายควรใช้keyหรือcode? โดยทั่วไปจะเป็นคีย์ทางกายภาพ แต่อาจขึ้นอยู่กับ Num Lock และรูปแบบด้วย ... แนวทางปฏิบัติที่ดีที่สุดคืออะไร?
Jake

16

MDN ได้จัดเตรียมแนวทางแก้ไขไว้แล้ว:

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
น่าเสียดายที่keyเป็นค่าสตริงเฉพาะของเบราว์เซอร์เช่น"Enter"หรือ"ArrowUp"และไม่มีวิธีที่เป็นมาตรฐานในการแปลงเป็นรหัสที่เกี่ยวข้อง ดังนั้นคุณจะต้องใช้รหัสสำเร็จรูปมากขึ้นในการแปลงระหว่างคีย์และรหัส
John Slegers

13

ตัวอย่างเช่นหากคุณต้องการตรวจสอบว่ามีการคลิกคีย์ "Enter" หรือไม่:

แทน

event.keyCode === 13

ทำเหมือน

event.key === 'Enter'

2
ในแง่ของส่วน "ในทางปฏิบัติ" ของคำถามนี้ควรเป็นคำตอบที่ยอมรับได้
Eduardo Pignatelli

-1

คุณสามารถใช้ได้

parseInt(event.key, radix: 10)

2
โปรดอย่าโพสต์โค้ดเพื่อเป็นคำตอบเท่านั้น แต่ยังให้คำอธิบายว่าโค้ดของคุณทำหน้าที่อะไรและแก้ไขปัญหาของคำถามได้อย่างไร คำตอบที่มีคำอธิบายมักจะมีประโยชน์มากกว่าและมีคุณภาพดีกว่าและมีแนวโน้มที่จะดึงดูดการโหวตมากขึ้น
Ran Marciano

-2
(e)=>{
  e.key === 'Escape';
}

เหมือนกับ

(e)=>{
  e.keyCode === 27;
}

ใช้อันที่สองจะดีกว่า


มันไม่ตอบคำถาม ทำไมถึงใช้ดีกว่าkeyCode? คุณได้ตรวจสอบคำตอบที่โหวตแล้วหรือยัง?
Zsolt Meszaros
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.