دليل أكواد مفاتيح JavaScript: فهم أحداث لوحة المفاتيح واستخدام keydown و key بأفضل طريقة
تُعد أحداث لوحة المفاتيح في JavaScript من الأدوات الأساسية التي تتيح للمطور تتبّع تفاعل المستخدم مع الأزرار أثناء الكتابة أو تنفيذ الاختصارات. ومن خلال الواجهة KeyboardEvent يمكن الوصول إلى مجموعة من الخصائص والأساليب التي تساعد على تفسير كل ضغطة مفتاح بصورة دقيقة.
تكمن أهمية هذا الموضوع في أن مواصفات الويب تتطور باستمرار؛ فبعض الخصائص القديمة أصبحت مهجورة، بينما ظهرت بدائل أحدث وأكثر موثوقية. لذلك يحتاج مطور الواجهة الأمامية إلى فهم ما يجب استخدامه اليوم، وما ينبغي تجنبه في المشاريع الحديثة.
في هذا الدليل سنغطي النقاط التالية:
- ما هي الواجهة
KeyboardEvent؟ - ما أنواع أحداث لوحة المفاتيح الأكثر أهمية عملياً؟
- متى نستخدم
keydownبدلاً منkeyupأوkeypress؟ - ما الخصائص الحديثة الموصى بها مثل
event.keyوevent.code؟ - ما الخصائص القديمة التي لم تعد مناسبة مثل
keyCodeوwhich؟ - جدول مرجعي مختصر لأشهر قيم المفاتيح.
ما هي الواجهة KeyboardEvent؟
الواجهة KeyboardEvent هي الكائن الذي تستقبله عند وقوع حدث متعلق بلوحة المفاتيح. يحتوي هذا الكائن على معلومات مهمة مثل اسم المفتاح المضغوط، ورمزه، وحالة مفاتيح التعديل مثل Ctrl وShift وAlt.
ترث الواجهة KeyboardEvent خصائصها من UIEvent، والتي بدورها ترث من Event. وهذا يعني أنك لا تحصل فقط على معلومات المفاتيح، بل أيضاً على الخصائص العامة الخاصة بالأحداث في المتصفح.

أنواع أحداث لوحة المفاتيح في JavaScript
هناك ثلاثة أنواع رئيسية من الأحداث المرتبطة بلوحة المفاتيح:
keydown: يُطلق عند الضغط على أي مفتاح.keypress: كان يُستخدم عند ضغط مفتاح ينتج قيمة حرفية، لكنه أصبح قديماً وغير موصى به.keyup: يُطلق عند رفع الإصبع عن المفتاح بعد الضغط عليه.
يمكنك إرفاق هذه الأحداث بأي عنصر HTML أو على الكائن document باستخدام الدالة addEventListener().
مثال على الاستماع لحدث keydown
let elem = document.getElementById('type-here');
elem.addEventListener("keydown", function (event) {
// event is a KeyboardEvent object
addRow(event);
});
مثال باستخدام معالج الحدث داخل العنصر
<input type="text" id="type-here" onkeyup="doSomething(event)">
وعند طباعة الكائن event داخل وحدة التحكم في المتصفح، ستظهر لك كل الخصائص المتاحة، بما فيها الخصائص الموروثة من UIEvent وEvent.

أداة تفاعلية لتجربة أحداث لوحة المفاتيح
من أفضل الطرق لفهم سلوك أحداث لوحة المفاتيح هو التجربة المباشرة. يمكنك استخدام الأداة التالية لاختبار المفاتيح ومعرفة قيم event.key وevent.code ونوع الحدث الناتج:
أي حدث يجب استخدامه: keydown أم keyup أم keypress؟
هذا السؤال من أكثر الأسئلة شيوعاً عند التعامل مع اختصارات لوحة المفاتيح أو نماذج الإدخال. والإجابة العملية في أغلب الحالات هي: استخدم keydown.
ترتيب تنفيذ الأحداث
إذا قمت بربط الأنواع الثلاثة بالعنصر نفسه، فغالباً سيكون ترتيب التنفيذ كالتالي:
keydownkeypressإذا كان المفتاح ينتج قيمة حرفيةkeyup
لماذا يُنصح باستخدام keydown؟
- يدعم عدداً أكبر من المفاتيح مقارنةً بـ
keypress. - يمكنه التقاط مفاتيح مثل
AltوCtrlوShiftوMeta. - مناسب للتعامل مع اختصارات مثل
Ctrl + ZوShift + Tab. - الحدث
keypressأصبح Deprecated، لذلك لا يُنصح بالاعتماد عليه في التطبيقات الحديثة.
الفرق بين keydown وkeyup
الفرق العملي بينهما مهم جداً:
- الحدث
keydownيقع قبل أن يعالج المتصفح المفتاح. - الحدث
keyupيقع بعد أن ينتهي المتصفح من معالجته. - إذا استخدمت
event.preventDefault()داخلkeydown، فيمكنك منع السلوك الافتراضي للمتصفح. - أما في
keyup، فغالباً يكون المتصفح قد نفّذ السلوك بالفعل.
يمكنك تجربة ذلك من خلال المثال التالي:
أهم خصائص KeyboardEvent التي تحتاجها فعلاً
رغم كثرة الخصائص المتوفرة، فإن عدداً محدوداً منها يكفي لمعظم الحالات العملية. الجدول التالي يلخص أهمها:
| الخاصية أو الدالة | الوصف | الحالة |
|---|---|---|
altKey |
تعيد قيمة منطقية توضح هل مفتاح Alt مضغوط أم لا. |
حديثة |
ctrlKey |
تعيد قيمة منطقية توضح هل مفتاح Control مضغوط أم لا. |
حديثة |
shiftKey |
تعيد قيمة منطقية توضح هل مفتاح Shift مضغوط أم لا. |
حديثة |
metaKey |
تعيد قيمة منطقية توضح هل أحد مفاتيح Meta مضغوطاً. |
حديثة |
key |
تمثل القيمة الفعلية للمفتاح المضغوط. | موصى بها |
code |
تمثل موضع المفتاح الفعلي على لوحة المفاتيح. | موصى بها |
getModifierState() |
تفحص حالة مفاتيح خاصة مثل CapsLock وNumLock. |
حديثة |
charCode |
كانت تعيد قيمة Unicode للحرف. |
مهجورة |
keyCode |
كانت تعيد القيمة الرقمية للمفتاح. | مهجورة |
which |
كانت تُستخدم أيضاً للحصول على القيمة الرقمية للمفتاح. | مهجورة |
لماذا event.key هو الخيار الأفضل؟
الخاصية event.key هي الأكثر ملاءمة في التطبيقات الحديثة، لأنها تعبّر عن القيمة الفعلية للمفتاح الذي ضغطه المستخدم، كما أن دعمها في المتصفحات الحديثة ممتاز.
إذا كنت تعمل على مشروع قديم يتطلب دعماً لمتصفحات أقدم، فيمكن استخدام event.which كحل احتياطي فقط، وليس كخيار رئيسي.
window.addEventListener("keydown", function (event) {
if (event.key !== undefined) {
// Handle with KeyboardEvent.key
} else if (event.which !== undefined) {
// Fallback for older browsers
}
});
مفاتيح التعديل Modifier Keys
مفاتيح التعديل هي المفاتيح التي تغيّر سلوك المفاتيح الأخرى عند استخدامها معها. من أشهرها:
ControlShiftAltMeta
يمكنك التعرف على حالتها من خلال خصائص مثل event.ctrlKey وevent.shiftKey وevent.altKey وevent.metaKey.
تنفيذ اختصارات لوحة المفاتيح عبر دمج أكثر من مفتاح
من الاستخدامات الشائعة لأحداث لوحة المفاتيح إنشاء اختصارات مخصصة داخل التطبيق، مثل التراجع أو الحفظ أو فتح نافذة معينة. هنا تظهر فائدة الجمع بين event.key ومفاتيح التعديل.
مثال على التقاط الاختصار Ctrl + Z
document.getElementById("to_focus").addEventListener("keydown", function (event) {
if (event.ctrlKey && event.key === "z") {
// تنفيذ إجراء مثل التراجع Undo
}
});
ولتجربة المزيد من الاختصارات عملياً:
الفرق بين event.key وevent.code
هذا الفرق مهم جداً عند بناء تطبيقات تعتمد على الإدخال الدقيق:
event.key: يعكس القيمة الفعلية التي نتجت عن الضغط، مثلaأوA.event.code: يعكس موضع المفتاح على اللوحة، مثلKeyA، بصرف النظر عن حالة الأحرف أو تخطيط اللغة.
بمعنى آخر، إذا ضغط المستخدم الحرف نفسه مع Shift، قد تختلف قيمة event.key، بينما تظل قيمة event.code مرتبطة بالمكان الفيزيائي للمفتاح.
جدول مرجعي لأشهر قيم مفاتيح لوحة المفاتيح
الجدول التالي يضم مجموعة مختصرة من أشهر المفاتيح وقيمها الأكثر استخداماً عملياً:
| اسم المفتاح | event.which |
event.key |
event.code |
ملاحظات |
|---|---|---|---|---|
| Backspace | 8 | Backspace |
Backspace |
– |
| Tab | 9 | Tab |
Tab |
– |
| Enter | 13 | Enter |
Enter |
– |
| Shift | 16 | Shift |
ShiftLeft / ShiftRight |
event.shiftKey تكون true |
| Control | 17 | Control |
ControlLeft / ControlRight |
event.ctrlKey تكون true |
| Alt | 18 | Alt |
AltLeft / AltRight |
event.altKey تكون true |
| Caps Lock | 20 | CapsLock |
CapsLock |
– |
| Escape | 27 | Escape |
Escape |
– |
| Space | 32 | |
Space |
قيمة key هي مسافة فعلية |
| Page Up | 33 | PageUp |
PageUp |
– |
| Page Down | 34 | PageDown |
PageDown |
– |
| End | 35 | End |
End |
– |
| Home | 36 | Home |
Home |
– |
| السهم الأيسر | 37 | ArrowLeft |
ArrowLeft |
– |
| السهم الأعلى | 38 | ArrowUp |
ArrowUp |
– |
| السهم الأيمن | 39 | ArrowRight |
ArrowRight |
– |
| السهم الأسفل | 40 | ArrowDown |
ArrowDown |
– |
| Insert | 45 | Insert |
Insert |
– |
| Delete | 46 | Delete |
Delete |
– |
الأرقام 0-9 |
48-57 | 0 إلى 9 |
Digit0 إلى Digit9 |
– |
الحروف a-z |
65-90 | a إلى z |
KeyA إلى KeyZ |
الحروف الكبيرة تغيّر key لا code |
| مفتاح النظام الأيسر | 91 | Meta |
MetaLeft |
event.metaKey تكون true |
| مفتاح النظام الأيمن | 92 | Meta |
MetaRight |
event.metaKey تكون true |
| القائمة السياقية | 93 | ContextMenu |
ContextMenu |
– |
لوحة الأرقام 0-9 |
96-105 | 0 إلى 9 |
Numpad0 إلى Numpad9 |
– |
| الضرب | 106 | * |
NumpadMultiply |
– |
| الجمع | 107 | + |
NumpadAdd |
– |
| الطرح | 109 | - |
NumpadSubtract |
– |
| الفاصلة العشرية | 110 | . |
NumpadDecimal |
– |
| القسمة | 111 | / |
NumpadDivide |
– |
F1 إلى F12 |
112-123 | F1 إلى F12 |
F1 إلى F12 |
– |
| Num Lock | 144 | NumLock |
NumLock |
– |
| Scroll Lock | 145 | ScrollLock |
ScrollLock |
– |
| الفاصلة المنقوطة | 186 | ; |
Semicolon |
في Firefox قد تختلف القيمة |
| علامة المساواة | 187 | = |
Equal |
في Firefox قد تختلف القيمة |
| الفاصلة | 188 | , |
Comma |
– |
| الشرطة | 189 | - |
Minus |
في Firefox قد تختلف القيمة |
| النقطة | 190 | . |
Period |
– |
| الشرطة المائلة | 191 | / |
Slash |
– |
| الاقتباس العكسي | 192 | ` |
Backquote |
– |
| القوس المربع الأيسر | 219 | [ |
BracketLeft |
– |
| الشرطة العكسية | 220 | \ |
Backslash |
– |
| القوس المربع الأيمن | 221 | ] |
BracketRight |
– |
| علامة الاقتباس المفردة | 222 | ' |
Quote |
– |
ملاحظات مهمة على التوافق بين المتصفحات
- الخاصية
event.whichأصبحت مهجورة، لذلك يجب عدم الاعتماد عليها في المشاريع الجديدة. - قد تختلف بعض القيم الرقمية في
Firefoxمقارنة بمتصفحات أخرى، خصوصاً لبعض الرموز الخاصة. - قيمة
event.codeتبقى ثابتة حسب موقع المفتاح، بينماevent.keyتعبّر عن الناتج الفعلي من الضغط.
ماذا عن لوحة المفاتيح الافتراضية في الهواتف والأجهزة اللوحية؟
في الأجهزة المحمولة أو لوحات المفاتيح الافتراضية، يعتمد سلوك الأحداث على مدى تشابه تخطيط لوحة المفاتيح مع لوحة المفاتيح التقليدية. إذا كان التخطيط والوظائف متقاربين، فغالباً ستحصل على قيم مناسبة في code وkey. أما إذا كان الإدخال مختلفاً بطبيعته، فقد لا تكون القيم مطابقة تماماً لما تتوقعه على الحاسوب.
أفضل الممارسات عند التعامل مع أحداث لوحة المفاتيح
- اعتمد على
keydownفي معظم السيناريوهات العملية. - استخدم
event.keyللتعرف على المفتاح المضغوط. - استخدم
event.codeعندما تحتاج إلى معرفة موقع المفتاح الفيزيائي. - تجنب
keypressلأنه حدث قديم ولم يعد مناسباً للمشاريع الحديثة. - تجنب
keyCodeوcharCodeوwhichإلا عند التعامل مع إرث برمجي قديم. - اختبر الاختصارات جيداً على أكثر من متصفح ونظام تشغيل، خصوصاً عند استخدام
Metaأو رموز خاصة.
الخلاصة التقنية
إذا كنت تبني واجهة ويب حديثة، فإن المزيج الأفضل غالباً هو استخدام الحدث keydown مع الخاصية event.key، وإضافة event.code فقط عندما تحتاج إلى التمييز بين مواضع المفاتيح نفسها. أما الخصائص القديمة مثل keyCode وwhich فلم تعد خياراً مناسباً إلا في حالات التوافق مع أنظمة قديمة. من منظور تقني وعملي، كلما اعتمدت على الواجهة الحديثة KeyboardEvent بطريقة صحيحة، أصبحت تطبيقاتك أكثر استقراراً وأسهل صيانة وأكثر توافقاً مع مستقبل الويب.
