Erfassen von Cmd-C- (oder Strg-C-)Tastaturereignissen aus der modularen Flex-Anwendung im Browser oder AIR

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

  •  09-06-2019
  •  | 
  •  

Frage

Es scheint unmöglich zu sein, das Tastaturereignis zu erfassen, das normalerweise zum Kopieren verwendet wird, wenn eine Flex-Anwendung im Browser oder als AIR-App ausgeführt wird, vermutlich weil der Browser oder das Betriebssystem es zuerst abfängt.

Gibt es eine Möglichkeit, den Browser oder das Betriebssystem anzuweisen, das Ereignis durchzulassen?

Beispielsweise habe ich in einem AdvancedDataGrid das Ereignis „keyUp“ auf „handleCaseListKeyUp(event)“ festgelegt, das die folgende Funktion aufruft:

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

Beim Ausführen kann ich die Taste „C“ nie loslassen, während ich gleichzeitig die Befehlstaste drücke (die als KeyboardEvent.ctrlKey angezeigt wird).Ich erhalte folgende Trace-Ergebnisse:

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

Wie Sie sehen, ist das einzige Ereignis, das ich erfassen kann, das Loslassen der Befehlstaste. Das Loslassen der „C“-Taste bei gedrückter Befehlstaste wird nicht einmal gesendet.

Hat irgendjemand die standardmäßige Tastaturhandhabung zum Kopieren und Einfügen erfolgreich implementiert?

Soll ich einfach nur die Taste „C“ verwenden (wie im Codebeispiel gezeigt) oder eine Schaltfläche zum Kopieren verfügbar machen?

Oder muss ich den Listener manuell auf einer höheren Ebene erstellen und das Ereignis in die Eingeweide meiner modularen Anwendung weiterleiten?

War es hilfreich?

Lösung

Ich habe einen Test durchgeführt, bei dem ich auf Key-Up-Ereignisse auf der Bühne lauschte und festgestellt habe, dass ich (auf meinem Mac) Strg-C, Strg-V usw. erfassen konnte.Alles in Ordnung, aber alles, was mit dem Befehl (der -Taste) zu tun hat, wurde erst erfasst, als ich die Befehlstaste losgelassen habe, und dann war ctrlKey falsch (obwohl in der Dokumentation angegeben ist, dass ctrlKey für die Befehlstaste auf dem Mac wahr sein sollte), und das charCode war 0.Kurz gesagt, ziemlich nutzlos.

Andere Tipps

Eine weitere unglaublich nervige Sache, die mir gerade aufgefallen ist, ist, dass Strg-C nicht erfasst werden kann event.ctrlKey && event.keyCode = Keyboard.C (oder ...event.charCode == 67), stattdessen müssen Sie testen charCode oder keyCodeSein 3.Es macht irgendwie Sinn charCode da Strg-C ist 3 in der ASCII-Tabelle, aber es macht keinen Sinn keyCode, das die Taste auf der Tastatur darstellen soll, nicht das eingegebene Zeichen.Das Gleiche gilt für alle anderen Tastenkombinationen (da jede Strg-Kombination ein ASCII-Äquivalent hat).

Bearbeiten Es wurde ein Fehler im Flex-Bug-System zu diesem Thema gefunden: https://bugs.adobe.com/jira/browse/FP-375

Ich habe eine Problemumgehung für dieses Problem gefunden, die auf der Erfassungssequenz basiert.Wenn Sie beispielsweise Cmd+A drücken, ist die Sequenz:

  • Typ:KEY_DOWN, Schlüsselcode 15
  • Typ:KEY_UP, Schlüsselcode 15
  • Typ:KEY_DOWN, Schlüsselcode 65

Wenn Sie also den KeyCode 15 nach unten und dann nach oben drücken und die nächste Aufnahme erfolgt, können Sie davon ausgehen, dass der Benutzer die Tastenkombination gedrückt hat.Meine Implementierung sieht am Ende so aus:

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

Bei mir funktioniert folgendes:

    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;
        }
    }
Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top