8

修正しようとしているjQueryUIウィジェットで非常に奇妙なjavascriptの動作と戦っています。IE7(Win XP)、jQuery 1.2.6(はい、古いバージョンです)。

ウィジェットはコンボボックスであり、キーボードイベントをキャプチャし、矢印キーに対して特別な動作をします。

フレックスボックスの入力フィールドに「&」文字を入力しようとすると、奇妙な動作が発生します。

フレックスボックスには次のようなコードがあります。

//initialization
$myInputElement.keypress($.flexbox.process_key);
$.flexbox.process_key = function process_key(e) {
    $.flexbox.flexboxFromInput(this).processKey(e);
    return true;
};

//on the flexbox object's prototype:
...
    processKey: function processKey(e) {
        var mod = 0;
            if (typeof (e.ctrlKey) !== 'undefined') {
                if (e.ctrlKey) mod |= 1;
                if (e.shiftKey) mod |= 2;
            } else {
                if (e.modifiers & Event.CONTROL_MASK) mod |= 1;
                if (e.modifiers & Event.SHIFT_MASK) mod |= 2;
            }
            ...
            switch (e.keyCode) {
                   case 38: // up
                       this.prevResult();
                       break;
                   case 40: // down
                       if (this.getCtr().is(':visible')) this.nextResult();
                       else this.flexboxDelay(true);
                       break;
               ...etc.
           }
    }
...

ロギングステートメントを紹介すると、「&」(shift + 7)を押すと3つのキー押下イベントが生成されることがわかります。

INFO: Flexbox> processKey, keyCode=16, ctrl=false, shift=true
INFO: Flexbox> processKey, keyCode=55, ctrl=false, shift=true
INFO: Flexbox> processKey, keyCode=38, ctrl=false, shift=true

どうやら、keyCode 38は上矢印キーであり、アンパサンドのASCIIコードでもありますか?

これを書いているときに、キー押下を「shift + 7」(keyCode 55)として検出してアンパサンドキーとして扱い、次のキー押下(38)を無視するように何らかのフラグを設定できることに気付きました。 )。これは恐ろしいハックのようです。

「&」などの特殊文字とIEの矢印キーを区別するためのより良い方法はありますか?

4

4 に答える 4

3

これは私がやったことです:

    /*
     * Hack around a wierd behavior in IE where "&%'(" have the same keyCodes
     * as the arrow keys.
     */
        if (keyCodeIn(e.keyCode, 55, 53, 57) && (mod & 2) && !(mod & 1)) {
            this.ignoreNextArrowKey = true;
        }
        else if (222 === e.keyCode && !(mod & 2) && !(mod & 1)) {
            this.ignoreNextArrowKey = true;
        }
        else if (keyCodeIn(e.keyCode, 38, 37, 39, 40) && this.ignoreNextArrowKey) {
            this.ignoreNextArrowKey = false;
            return;
        }

        //...

        function keyCodeIn(keyCode) {
            for(var i = 1; i < arguments.length; i++) {
                if (arguments[i] === keyCode) {
                    return true;
                }
            }
            return false;
        }

これが誰かに役立つことを願っています。このコードを再利用する場合は、参照するオブジェクトに応じて、キーワード「this」の使用法を調整する必要があります(ここでは、フレックスボックスウィジェットに関連付けられたjavascriptオブジェクトです)。

編集:このコードを更新し、以前に存在していた正規表現テストを削除しました。これはバグがあることを発見しました。

于 2010-03-04T00:38:22.130 に答える
2

keydownよりも信頼性の高いデータが得られると思いますkeypress

于 2010-03-04T00:15:51.553 に答える
1

このjqueryライブラリを使用して、キーを押すためのカスタムハンドラーを作成することをお勧めします: http ://code.google.com/p/js-hotkeys/

キーコードを論理的に識別しようとするのは悪夢です。

于 2010-03-04T11:44:28.737 に答える
0

キーを上または下に押すと、「&」の場合は55、「上矢印」の場合は38のkeyCodeが返されます。

于 2010-03-04T02:54:49.253 に答える