.keyCode vs. . ซึ่ง


228

ฉันคิดว่านี่จะได้รับคำตอบที่ไหนสักแห่งใน Stack Overflow แต่ฉันหามันไม่เจอ

หากฉันกำลังฟังเหตุการณ์ปุ่มกดฉันควรใช้.keyCodeหรือ.whichเพื่อตรวจสอบว่ากดแป้น Enter หรือไม่

ฉันทำสิ่งต่อไปนี้เสมอ:

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

แต่ฉันเห็นตัวอย่างที่ใช้แทน.which .keyCodeความแตกต่างคืออะไร? ข้ามเบราว์เซอร์หนึ่งเป็นมิตรมากกว่าอีก?


1
ทั้งสองสิ่งนี้ได้รับการพิจารณาว่าเลิกใช้แล้วในตอนนี้ FYI developer.mozilla.org/en-US/docs/Web/API/KeyboardEvent/which developer.mozilla.org/en-US/docs/Web/API/KeyboardEvent/keyCode
CodeFinity

คำตอบ:


209

หมายเหตุ:คำตอบด้านล่างนี้ถูกเขียนขึ้นในปี 2010 ที่นี่หลายปีต่อมาทั้งคู่keyCodeและwhichเลิกใช้แล้วkey(สำหรับคีย์ตรรกะ) และcode(สำหรับตำแหน่งทางกายภาพของคีย์) แต่โปรดทราบว่า IE ไม่รองรับcodeและการสนับสนุนkeyนั้นขึ้นอยู่กับข้อมูลจำเพาะรุ่นเก่าดังนั้นจึงไม่ค่อยถูกต้องนัก ขณะที่ฉันเขียนสิ่งนี้ Edge ปัจจุบันที่ใช้ EdgeHTML และ Chakra ก็ไม่รองรับcodeเช่นกัน แต่ Microsoft กำลังเปิดตัวBlink - และV8 ที่ใช้แทน Edge สำหรับ Edge ซึ่งน่าจะเป็นไปได้


เบราว์เซอร์บางคนใช้keyCodeคนอื่น ๆ whichใช้

หากคุณกำลังใช้ jQuery คุณได้อย่างน่าเชื่อถือสามารถใช้whichเป็น jQuery มาตรฐานสิ่ง ; เพิ่มเติมที่นี่

หากคุณไม่ได้ใช้ jQuery คุณสามารถทำได้:

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

หรืออีกทางหนึ่ง:

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

... ซึ่งจัดการความเป็นไปได้ที่e.whichอาจเกิดขึ้น0(โดยการเรียกคืนนั้น0ในตอนท้ายโดยใช้โอเปอเรเตอร์ที่ทรงพลังของ JavaScript|| )


2
ขอบคุณ TJ ฉันจะหาข้อมูลอ้างอิงได้จากที่ไหน ไม่ใช่ว่าฉันไม่เชื่อคุณฉันแค่อยากรู้! ... ฉันเห็นคุณเพิ่งเพิ่มนั่นขอบคุณ ดังนั้นแม้สำหรับผู้ที่ไม่ได้ใช้ jquery,. ซึ่งเป็นตัวเลือกที่ดีกว่า?
ScottE

7
@ScottE: หากไม่ได้ใช้ jQuery คุณต้องจัดการเรื่องนี้ด้วยตัวเองอย่างชัดเจน ฉันมักจะทำเช่นนี้var key = event.which || event.keyCode;ที่จะใช้event.whichถ้ามันถูกกำหนดและไม่เท็จหรือevent.keyCodeถ้าwhichไม่ได้กำหนดหรือเท็จ ในทางเทคนิคแล้วฉันควรจะทำvar key = typeof event.which === "undefined" ? event.keyCode : event.which;แต่ถ้าevent.whichเป็น0(เป็นได้0หรือไม่) ฉันไม่น่าสนใจในสิ่งที่ฉันทำ
TJ Crowder

2
@ScottE ต่อไปนี้เป็นข้อมูลอ้างอิงพื้นฐาน: quirksmode.org/js/keys.html (ไม่รวมwhichซึ่งฉันคิดว่าให้บริการโดย jQuery เท่านั้น แต่ฉันไม่แน่ใจ 100% แต่คุณควรเริ่มเห็น ความแตกต่างในเบราว์เซอร์)
Mottie

1
@fudgey: whichให้บริการkeypressโดยเบราว์เซอร์ทั้งหมดยกเว้น IE และ quirksmode ไม่ได้มีสิทธิ์ที่นี่ เป็นข้อมูลอ้างอิงการเชื่อมโยงที่ @TJ เดโพสต์จะดีมาก: unixpapa.com/js/key.html
Tim Down

5
@TJ Crowder: ใช่whichคุณสมบัติของกิจกรรมอาจเป็นศูนย์และสิ่งนี้สามารถสร้างความแตกต่างอย่างมากให้กับแอปพลิเคชันส่วนใหญ่ ยกตัวอย่างเช่นปุ่มที่ไม่พิมพ์ใน Firefox มีwhichทรัพย์สินของศูนย์และเดียวกันคุณสมบัติเป็นkeyCode keydownปุ่ม Home มีkeyCodeจำนวน 36 บนพีซีของฉันใน Firefox ซึ่งเป็นรหัสอักขระสำหรับ "$" ซึ่งจะทำให้แยกความแตกต่างระหว่างผู้ใช้ที่กดปุ่ม Home และผู้ใช้ที่พิมพ์อักขระ $ โดยใช้event.which || event.keyCodeไม่ได้
Tim Down

32

jQuery normalises event.whichขึ้นอยู่กับว่าevent.which, event.keyCodeหรือevent.charCodeได้รับการสนับสนุนโดยเบราเซอร์:

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

ข้อดีอีกอย่างของ.whichjQuery คือการคลิกเมาส์ด้วย:

// 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 ให้event.wich == null && ...ทดสอบ null หรือไม่ได้กำหนดเท่านั้น event.wich || ...การทดสอบของคุณเป็นเท็จ (ไม่ได้กำหนด, ไม่มีค่า, เป็นเท็จ, 0, '', ฯลฯ )
aMarCruz

@aMarCruz Falsy ตามวัตถุประสงค์ เช่นbugs.webkit.org/show_bug.cgi?id=167350ที่มีการรายงาน Webkit และฉันไม่คิดว่าจะตรวจสอบ""หรือ[]เจ็บปวด
Anne van Rossum

20

หากคุณยังคงอยู่ใน Javilla โปรดทราบว่ารหัสตอนนี้เลิกใช้แล้วและจะถูกทิ้ง:

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

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

ให้ใช้: .keyหรือ. code แทนขึ้นอยู่กับพฤติกรรมที่คุณต้องการ: https://developer.mozilla.org/en-US/docs/Web/API/KeyboardEvent/code https://developer.mozilla.org/en -US / เอกสาร / Web / API / KeyboardEvent / คีย์

ทั้งสองถูกนำไปใช้กับเบราว์เซอร์ที่ทันสมัย


.codeสอดคล้องกับตำแหน่งทางกายภาพของคีย์บนแป้นพิมพ์ในขณะที่. key สอดคล้องกับตัวละครที่สร้างขึ้นโดยปุ่มกดโดยไม่คำนึงถึงตำแหน่ง
Christopher

1
ทั้ง 'รหัส' และ 'คีย์' มีนิสัยใจคอในเบราว์เซอร์ที่ทันสมัย การใช้ตัวอย่าง "ทดลองใช้" บน MDN developer.mozilla.org/en-US/docs/Web/API/KeyboardEvent/codeในเบราว์เซอร์ที่แตกต่างกันแสดงว่า IE11 / IE Edge ไม่ได้ใช้ 'รหัส' และ 'คีย์' การใช้งานไม่ตรงกับการใช้งานใน Chrome / FF / Safari (ความแตกต่างที่ปรากฏส่วนใหญ่จะอยู่ในตัวควบคุมเช่น Escape และ Enter) ฉันคิดว่าการใช้ห้องสมุดอาจจะง่ายที่สุดเว้นแต่คุณจะเต็มใจรับผิดชอบเรื่องความไม่แน่นอนเหล่านี้ด้วยตัวคุณเอง ฉันต้องการให้นี่เป็นคำตอบจริง ๆ แต่ IE ก็แก้ปัญหานี้ด้วย :-(
Akrikos

อืม ... จริง ๆ แล้วมันไม่ได้เลวร้ายเกินไปที่จะใช้คีย์ในทางข้ามเบราว์เซอร์ ปุ่มตัวอักษรและตัวเลขปกติเพียงแค่คืนค่าของพวกเขาและสำหรับปุ่มควบคุม (escape, enter, tab, ฯลฯ ) ปรากฏว่ามีการใช้งานเหมือนกันในเบราว์เซอร์ส่วนใหญ่ยกเว้น IE11 / Edge ซึ่งใช้เวอร์ชั่นเก่ากว่าของ spec สำคัญ.
Akrikos

ผมจะแนะนำให้ใช้แทนkey codeตัวอย่างเช่นถ้าคุณมีแป้นพิมพ์กับสื่อควบคุมปุ่มกดเล่น / หยุดชั่วคราวเอาท์พุท "MediaPlayPause" สำหรับkeyและ "" codeสำหรับ
thdoan

6

ดูที่นี่: https://developer.mozilla.org/en-US/docs/Web/API/event.keyCode

ในเหตุการณ์ keypress ค่า Unicode ของคีย์ที่กดจะถูกเก็บไว้ในคุณสมบัติ keyCode หรือ charCode ไม่เคยทั้งสองอย่าง หากคีย์ที่กดสร้างอักขระ (เช่น 'a') charCode จะถูกตั้งค่าเป็นรหัสของตัวละครนั้นโดยคำนึงถึงตัวอักษรพิมพ์ใหญ่ (เช่น charCode คำนึงถึงว่าปุ่ม Shift นั้นถูกพักไว้หรือไม่) มิฉะนั้นรหัสของคีย์ที่กดจะถูกเก็บไว้ใน keyCode keyCode ตั้งค่าเสมอในการดาวน์คีย์และเหตุการณ์คีย์อัพ ในกรณีเหล่านี้ charCode จะไม่ถูกตั้งค่า ในการรับโค้ดของคีย์โดยไม่คำนึงว่าเก็บไว้ใน keyCode หรือ charCode ให้ค้นหาคุณสมบัติใด อักขระที่ป้อนผ่าน IME ไม่ได้ลงทะเบียนผ่าน keyCode หรือ charCode


6

ฉันแนะนำevent.keyในขณะนี้ เอกสาร MDN: https://developer.mozilla.org/en-US/docs/Web/API/KeyboardEvent/key

event.KeyCodeและevent.whichทั้งคู่มีคำเตือนที่คัดค้านอย่างน่ารังเกียจที่ด้านบนสุดของหน้า MDN:
https://developer.mozilla.org/en-US/docs/Web/API/KeyboardEvent/keyCode https://developer.mozilla.org/en-US / เอกสาร / Web / API / KeyboardEvent / ซึ่ง

สำหรับคีย์ตัวอักษรและตัวเลขevent.keyดูเหมือนว่าจะมีการใช้งานเหมือนกันในทุกเบราว์เซอร์ สำหรับปุ่มควบคุม (แท็บป้อนหนี ฯลฯ )event.keyมีค่าเดียวกันทั่วทั้ง Chrome / FF / Safari / Opera แต่ค่าที่แตกต่างใน IE10 / 11 / Edge (เห็นได้ชัดว่า IEs ใช้รุ่นที่เก่ากว่าของสเป็ค แต่ตรงกับกัน ของ 14 มกราคม 2018)

สำหรับปุ่มตัวอักษรและตัวเลขการตรวจสอบจะมีลักษณะดังนี้:

event.key === 'a'

สำหรับตัวควบคุมคุณต้องทำสิ่งต่อไปนี้:

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

ฉันใช้ตัวอย่างที่นี่เพื่อทดสอบกับเบราว์เซอร์หลายตัว (ฉันต้องเปิดใน codepen และแก้ไขเพื่อให้ทำงานกับ IE10 ได้): https://developer.mozilla.org/en-US/docs/Web/API/KeyboardEvent/ รหัส

event.code ถูกกล่าวถึงในคำตอบที่แตกต่างกันว่าเป็นไปได้ แต่ IE10 / 11 / Edge ไม่ได้ใช้มันดังนั้นมันจะออกมาถ้าคุณต้องการการสนับสนุน IE


2

ห้องสมุด Javascript ที่แข็งแกร่งสำหรับการจับแป้นพิมพ์และการป้อนคีย์ผสม มันไม่มีการพึ่งพา

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

องเข้าใจการปรับเปลี่ยนต่อไปนี้: , shift, option, , alt, ctrl, control,commandและและ

ปุ่มพิเศษดังต่อไปนี้สามารถนำมาใช้สำหรับทางลัด: backspace, tab, clear, enter, return, esc, escape, space, up, down, left, right, home, end, pageup, pagedown, del, deleteและผ่านf1f19


มันจะ shim Array.prototype.indexOf ดังนั้นถ้าคุณใช้สิ่งนี้ในห้องสมุดอื่นมันอาจไม่เหมาะสมเพราะมันจะปรับเปลี่ยนขอบเขตทั่วโลก event.keyCodeนอกจากนี้ยังปรากฏการใช้เลิกใช้
Akrikos

ห้องสมุดนี้ตรวจไม่พบ Fn บนแล็ปท็อป Vaio ของฉัน
thdoan

0

ใน Firefox คุณสมบัติ keyCode ไม่ทำงานในเหตุการณ์ onkeypress (จะคืนค่าเป็น 0 เท่านั้น) สำหรับโซลูชันข้ามเบราว์เซอร์ให้ใช้คุณสมบัติใดพร้อมกับรหัสคีย์เช่น:

var x = event.which || event.keyCode;  // Use either which or keyCode, depending on browser support
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.