التقاط حدث لوحة المفاتيح Cmd-C (أو Ctrl-C) من تطبيق Flex المعياري في المتصفح أو AIR

StackOverflow https://stackoverflow.com/questions/31849

  •  09-06-2019
  •  | 
  •  

سؤال

يبدو أنه من المستحيل التقاط حدث لوحة المفاتيح المستخدم عادةً للنسخ عند تشغيل تطبيق Flex في المتصفح أو كتطبيق AIR، ربما لأن المتصفح أو نظام التشغيل يعترضه أولاً.

هل هناك طريقة لإخبار المتصفح أو نظام التشغيل بالسماح للحدث بالمرور؟

على سبيل المثال، في AdvancedDataGrid، قمت بتعيين حدث keyUp إلى HandleCaseListKeyUp(event)، والذي يستدعي الوظيفة التالية:

        private function handleCaseListKeyUp(event:KeyboardEvent):void
        {
            var char:String = String.fromCharCode(event.charCode).toUpperCase();

            if (event.ctrlKey && char == "C")
            {
                trace("Ctrl-C");
                copyCasesToClipboard();
                return;
            }

            if (!event.ctrlKey && char == "C")
            {
                trace("C");
                copyCasesToClipboard();
                return;
            }

            // Didn't match event to capture, just drop out.
            trace("charCode: " + event.charCode);
            trace("char: " + char);
            trace("keyCode: " + event.keyCode);
            trace("ctrlKey: " + event.ctrlKey);
            trace("altKey: " + event.altKey);
            trace("shiftKey: " + event.shiftKey);
        }

عند التشغيل، لا يمكنني أبدًا تحرير المفتاح "C" أثناء الضغط أيضًا على مفتاح الأمر (الذي يظهر كـ KeyboardEvent.ctrlKey).أحصل على نتائج التتبع التالية:

charCode: 0
char: 
keyCode: 17
ctrlKey: false
altKey: false
shiftKey: false

كما ترون، الحدث الوحيد الذي يمكنني التقاطه هو تحرير مفتاح الأمر، ولا يتم حتى إرسال تحرير المفتاح "C" أثناء الضغط على مفتاح الأمر.

هل نجح أي شخص في تنفيذ التعامل مع النسخ واللصق القياسي للوحة المفاتيح؟

هل من المقدر لي أن أستخدم المفتاح "C" بمفرده (كما هو موضح في مثال الكود) أو أن أجعل زر النسخ متاحًا؟

أو هل أحتاج إلى إنشاء المستمع يدويًا على مستوى أعلى وتمرير الحدث إلى أعماق تطبيقي المعياري؟

هل كانت مفيدة؟

المحلول

لقد أجريت اختبارًا حيث استمعت إلى الأحداث الرئيسية على المسرح ولاحظت أنه (على جهاز Mac الخاص بي) يمكنني التقاط Control-c وcontrol-v وما إلى ذلك.على ما يرام، ولكن لم يتم التقاط أي شيء يتضمن الأمر (المفتاح ) حتى قمت بتحرير مفتاح الأمر، وبعد ذلك كان ctrlKey خطأ (على الرغم من أن المستندات تنص على أن ctrlKey يجب أن يكون صحيحًا بالنسبة لمفتاح الأمر على جهاز Mac)، و كود شار كان 0.عديمة الفائدة جدا، باختصار.

نصائح أخرى

شيء آخر مزعج للغاية أدركته للتو هو أنه لا يمكن التقاط ctrl-c event.ctrlKey && event.keyCode = Keyboard.C (أو ...event.charCode == 67)، بدلاً من ذلك عليك اختباره charCode أو keyCodeكون 3.إنه نوع من المنطقي ل charCode منذ ctrl-c هو 3 في جدول ASCII، ولكن هذا لا معنى له keyCode, ، والذي من المفترض أن يمثل المفتاح الموجود على لوحة المفاتيح، وليس الحرف المكتوب.الأمر نفسه ينطبق على جميع مجموعات المفاتيح الأخرى (لأن كل مجموعة ctrl لها مكافئ ASCII).

يحرر تم العثور على خطأ في نظام Flex bug حول هذا: https://bugs.adobe.com/jira/browse/FP-375

لقد وجدت حلاً واحدًا لهذا الحل استنادًا إلى تسلسل الالتقاط.عندما تضغط على Cmd+A، على سبيل المثال، يصبح التسلسل:

  • يكتب:KEY_DOWN، رمز المفتاح 15
  • يكتب:KEY_UP، رمز المفتاح 15
  • يكتب:KEY_DOWN، رمز المفتاح 65

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

    protected var lastKeys:Array;
    this.stage.addEventListener(KeyboardEvent.KEY_DOWN, keyHandler, false, 0, true);
    this.stage.addEventListener(KeyboardEvent.KEY_UP, keyHandler, false, 0, true);

    private function getCmdKey(ev:KeyboardEvent):Boolean {
        this.lastKeys.push(ev);
        this.lastKeys = this.lastKeys.splice(Math.max(0, this.lastKeys.length-3), 3);

        if (this.lastKeys.length < 3) return false;

        if (ev.keyCode != 15 && ev.type == KeyboardEvent.KEY_UP) {
            var firstKey:KeyboardEvent = this.lastKeys[0] as KeyboardEvent;
            var secondKey:KeyboardEvent = this.lastKeys[1] as KeyboardEvent;

            if (firstKey.keyCode == 15 && firstKey.type == KeyboardEvent.KEY_DOWN &&
                secondKey.keyCode == 15 && secondKey.type == KeyboardEvent.KEY_UP) {
                    return true;
            }
        }

        return false;
    }

    private function keyHandler(ev:KeyboardEvent):void {
        var cmdKey:Boolean = this.getCmdKey(ev.clone() as KeyboardEvent);
        var ctrlKey:Boolean = ev.ctrlKey || cmdKey;

        if (ctrlKey) {
            if (ev.keyCode == 65) { 
                // ctrl + "a"-- select all!
            }
        }
    }

بالنسبة لي الأعمال التالية:

    private var _ctrlHoldFlag:Boolean = false; 

    // Do something if CTRL was held down and C was pressed
    // Otherwise release the ctrl flag if it was pressed
    public function onKey_Up(event:KeyboardEvent):void {  
        var keycode_c:uint = 67;

        if (_ctrlHoldFlag && event.keyCode == keycode_c)
        {
            //do whatever you need on CTRL-C
        }

        if (event.ctrlKey)
        {
            _ctrlHoldFlag = false;
        }
    }

    // Track ctrl key down press 
    public function onKey_Down(event:KeyboardEvent):void
    {
        if (event.ctrlKey)
        {
            _ctrlHoldFlag = true;
        }
    }
مرخصة بموجب: CC-BY-SA مع الإسناد
لا تنتمي إلى StackOverflow
scroll top