معالجة ضغطات المفاتيح المعروفة اختصارات وتصحيح الأخطاء

مرحبا سنتحدث عن المفاتيح الساخنة في WEBAPI + JavaScript ، وسننظر في أساليب تنظيمهم والمشاكل التي تنشأ أساسًا في التطبيقات الكبيرة.


النظر في طرق للتعامل مع مفاتيح مهمة محددة.


"المهمة"


تخيل أنك في مشروع موجود تحتاج إلى تنفيذ معالجة إدخال لوحة المفاتيح. في الوقت نفسه ، واجهة المشروع ووحدات التحكم فيه ، لأسباب تاريخية بحتة ، بالطبع ، كما هي. وهناك ما يلي:


ParentController التي يوجد فيها مكونان مع ParentController . Controller1 وعنصر يستخدم CTRL+SHIFT+F للبحث في الموقع ، و Controller2 مع عنصر DOM الخاص به ، وهو منطقة محلية ، حيث يوجد بحث داخله. ومع ذلك ، يمكن أن تكون في وقت واحد على الشاشة. فيما يلي بعض الطرق لحل هذه المشكلة.


1. " KeyboardEvent والمعالجة اليدوية"


تصف كائنات KeyboardEvent كيفية تفاعل المستخدم مع لوحة المفاتيح. يتم وصف كل حدث بواسطة مفتاح ؛ يحدد نوع الحدث (keydown أو keypress أو keyup) نوع الإجراء الناتج.


يبدو عظيم حق؟ دعنا نلقي نظرة فاحصة.
فكر في اعتراض الضغط على CTRL+SHIFT+F ، والذي عادة ما يتوافق مع مكالمة بحث عمومية.


 element.addEventListener('keypress', (event) => { const keyName = event.key; //        // ..     SHIFT      if (event.ctrlKey && event.shiftKey && event.key.toLowerCase() === 't') { alert('CTRL+SHIFT+T pressed'); } }); 

الآن ، تنطبق على مهمتنا ، يمكنك القيام بطريقتين (على سبيل المثال)


تنفيذ اعتراض المفاتيح في وحدات التحكم 1 و 2 بشكل منفصل


سيؤدي ذلك إلى حقيقة أنه بناءً على الطلب الوارد في DOM ، قد تحتاج إلى useCapture لضمان ترتيب معالجة Controller2 ثم Controller1. لذا تحصل على منطق معزول ، ولكن إذا كان التطبيق معقدًا وهناك الكثير من وحدات التحكم هذه ، فإن هذا الحل ليس جيدًا بسبب ذلك يمكن أن يكون بعضها في وقت واحد على الشاشة ويمكن أن يكون لديهم ترتيب معالجة صارم خاص بهم ، والذي لا يعتمد على موضعهم في شجرة DOM. (انظر الفقاعات والتقاط )


القبض على مفتاح في CommonController


الحل البديل هو التعامل مع النقرات في وحدة تحكم رئيسية مشتركة ، والتي تعرف بالضبط متى تظهر أطفالها ، والتي تتحكم فيها وحدات التحكم الأولى والثانية. هذا مع زيادة وحدات التحكم التابعة لن يسبب صعوبات في اصطياد الأحداث وتحديد وحدة التحكم لمعالجة المفاتيح. ومع ذلك ، ستكون هناك مشكلة أخرى - وهي if كثيفة if ظهرت في وحدة التحكم الأصل ، والتي تعالج جميع الحالات المحتملة. للتطبيقات الكبيرة ، هذا الحل غير مناسب ، لأن في مرحلة ما ، قد يظهر Controller آخر ليس ParentController إلى ParentController المعالج بمستوى واحد إلى الوالد المشترك وما إلى ذلك ... حتى تبدأ عاجلاً أو آجلاً إحدى وحدات التحكم في معرفة الكثير عن العناصر الموجودة بداخلها.



في الواقع ، 80 ٪ فقط من المتصفحات قادرة على العمل مع KeboardEvent.key ، في جميع البقية ستحتاج إلى تشغيل KeboardEvent.keyCode : Number مع رموز المفاتيح. مما يعقد الحياة كثيرا. هنا يستحق الذهاب إلى وصف عيوب هذا النهج.


سلبيات:


  • تنظيم الكود ليس ملائمًا جدًا ، ويلزم وجود بطاقة من رموز الأحرف وما يعادلها للنص ، كما أن الأدوات المساعدة الأخرى تقلل من حجم الكود في المعالجات.
  • 80٪ دعم المتصفحات للعمل مع الرموز دون استخدام أكوادها لا يزال غير كافٍ.
  • التداخل باستخدام useCapture معالج إلى آخر.
  • إذا كان هناك useCapture مع useCapture وعناصر متداخلة مع نفس المعالجات
    تصحيح الأخطاء أمر صعب.
  • ضعف التدرجية.

لكن أصلاً ، لا توجد تبعيات ومكتبات غير ضرورية


بعد ذلك ، سنتحدث عن مكتبتين ، إحداهما مصممة لحل مشكلاتهما المشابهة.


2. "استخدام مكتبة HotKeys "


ثلاثة آلاف النجوم على جيثب ، حجم متواضع وعدم وجود التبعيات. الشركة المصنعة الصينية ، تعدنا بحل يناسب الجميع. ولكن دعونا لا نتسرع. دعونا نحاول حل مشكلتنا بمساعدتها.


 //   hotkeys('ctrl+shift+f', function(event, handler){ alert('CTRL+SHIFT+T pressed'); }); 

يبدو بناء الجملة أقصر بكثير بالفعل ، وستظهر الشريحة الرئيسية لحل المشكلة مباشرةً مكونات وحدات التحكم 1 و 2 على الشاشة. بعد البحث قليلاً في رمز المكتبة ، من السهل أن تلاحظ أن معالجات تشكل مكدسًا ممتلئًا أو محوًا أثناء تسجيلهم ويعرف أيضًا باسم الظهور على الشاشة (دعنا نقول أن عنصرًا يحتوي على معالج ظهر فيما بعد العنصر الحالي سيكون له الأولوية في قائمة الانتظار لمعالجة المفاتيح الساخنة).


يحدث غالبًا أن يظهر العنصر الذي يجب أن يعترض المعالجة لاحقًا. في هذه الحالة ، يمكننا نشر منطق معالجة النقرات بأمان إلى كل وحدة تحكم. وستساعدنا شرائح أخرى مثل النطاقات على فصل مجموعة من النقرات عن الأخرى. ولكن في حالة ظهور - تنشأ نفس المشكلات كما هو الحال في eventListener الأصلي. سيكون لدينا لوضع كل شيء في وحدة تحكم الأصل المشترك.


بالإضافة إلى ذلك ، يحدث غالبًا أنك تحتاج إلى حظر السلوك الافتراضي ، ولكن لا يعتبر الحدث معالجًا (بمعنى آخر ، لا يوجد فهم لا لبس فيه ما إذا كان الحدث قد تمت معالجته أم لا إذا تلقيناه) أو يجب معالجته بواسطة وحدتي تحكم في وقت واحد. سيؤدي أحدها إلى رد فعل على السلوك ، والآخر سيأخذ بعين الاعتبار ببساطة أن الحدث كان.


إجمالي الإيجابيات:


  • نطاق يسمح لك لفصل تيارات.
  • بناء الجملة واضح وقصير.
  • يحدد الترتيب مظهر العنصر ، وليس الموضع في DOM.
  • حجم وقلة التبعيات.

سلبيات:


  • يمكن معالجة نطاق واحد فقط في وقت واحد
  • لا يزال التصحيح صعبًا بسبب استدعاءات الدوال في الحلقة ، وقد لا يكون معروفًا في أي معالج ضائع الحدث التعامل معها
  • العبارة التي تتم معالجتها الحدث إذا كان يحتوي على علامة defaultPrevented وتم مقاطعة التوزيع الخاص به غير صحيح.
  • وظائف عالمية لتسجيل المكالمات وإلغاء الاشتراك في الأحداث

إنها مناسبة لحل المهام النموذجية ، ولكن ستكون هناك مشاكل في كتابة محطة تداول أو لوحة إدارة كبيرة ، لتصحيح الأخطاء بشكل صحيح.


3. "استخدام مكتبة اختصارات المكدس "


نتيجة للعديد من المشاحنات ومحاولات استخدام حل شخص آخر ، اضطررت إلى إجراء حل الدراجة مكتبة ستساعد ، أولاً وقبل كل شيء ، على الظهور لأول مرة بشكل طبيعي ، والحفاظ على أفضل خصائص الخصائص الشعبية وجلب شيء جديد.


ما المهام التي تم حلها عند الخلق؟


  • رد الفعل مبدأ العملية
  • معالجات تصحيح بسيطة
  • حالة معالجة حدث لا لبس فيها
  • عبر منصة
  • راحة الاستيراد وعدم وجود وظائف عالمية
  • لا يوجد نافذة الوصول المباشر عند الاتصال
  • لا حاجة لاستدعاء stopPropagation أو stopPropagation

 //  this.shortcuts = shortcuts({ 'CMD+SHIFT+F': function (event, next) { alert('CMD+SHIFT+F pressed'); } }); //  this.shortcuts.destroy(); 

ينطبق هذا على مهمتنا ، يتزامن الحل تمامًا مع المكتبة السابقة. لم يحدث بعد الفصل الكامل لمنطق المعالجة دون معرفة الكثير عن بعضها البعض ، ولكن أصبح الكثير أبسط وأكثر قابلية للفهم. شكرا لما يلي:


  • لا يوجد حتى الآن أي ربط بـ DOM (باستثناء مستمع واحد) ويتم تعبئة مكدس المعالجات وفقًا للترتيب الذي تم تسجيلهم به.
  • رفضوا على الفور استخدام scope للعزلة. ليس من الواضح ما هي المهام التي يحلها ويبدو أنه يعقد البنية فقط.
  • التصحيح والوظيفة التالية حول هذا الموضوع ربما تستحق المزيد ...
  • الطفرات في أحداث البيانات التي يحملها في event.detail

يتم ترتيب "معالجات تصحيح الأخطاء" بحيث يتم تشكيل callstack منها قبل الاستدعاء. يسمح لك بمشاهدة سلسلة الأحداث كاملة في وحدة التحكم من المعالج الأول إلى التالي في وحدة التحكم.


next () - استدعاء دالة يعني أنه لم تتم معالجة الحدث وسيتم تمريره إلى المعالج التالي. عقد مألوف للغاية ينطبق على معالجات وسيطة أو الوسيطة في express . لذلك ستعرف دائمًا ما إذا كان الحدث قد تمت معالجته أو تم تحويره أو "أخذه في الاعتبار".



هكذا يبدو مكدس الاتصال إذا قمت بتعيين نقطة توقف في أحدها.


حسنا ، حول سلبيات:


  • لا توجد مخطوطة مكتوبة بعد.
  • لا نطاقات - لا يمكن إنشاء موقع splitscreen)
  • تركيبة واحدة أثناء التسجيل (هذه ليست CMD+F,CMD+V,T لن تفهم الفاصلة)

Source: https://habr.com/ru/post/ar438770/


All Articles