1

キーボードショートカットを自分のWebページに自動的にバインドするJavascript/jQuery関数を作成しようとしています。私が考えている方法は次のようなものです。

  1. 'key-'で始まるクラスを持つすべての要素をループします
  2. これらの要素ごとに、クラスからキーの組み合わせを取得します。たとえば、「key-ctrl-s」はCtrl+を返します。S
  3. これらの特定のキーの組み合わせのイベントをドキュメントにバインドします

かなり基本的なアルゴリズム、またはそう思った...問題が来る...

したがって、たとえば、次のように入力できます。

<a href="javascript:void(0)" class="some_other_class ctrl+s">Save</a>
<a href="javascript:void(0)" class="ctrl+shift+s">Save As</a>

上記のコードは、次のキーボードショートカットを生成します:Ctrl+SおよびCtrl++ShiftS

そして、これらのキーが押されるclickと、関連するhtml要素に対してイベントがトリガーされます...

問題

上で述べたように、ここでのアルゴリズムは非常に単純ですが、いつものように、それを書き込もうとすると問題が発生します。

e.whichイベントを自動的にバインドするときに、どのキーコード()をリッスンするかをどのように知ることができますか。

例えば:

上記のHTMLと次のjQueryを使用して、これまでのところ取得できます(正規表現などは無視してください)。

function keyboardShortcuts(){
    // Loop through all elements with a class containing 'key-'
    $("[class*='key-']").each(function(){
        // Using a regular expression here, separate the class into individual keys
        // whilst ignoring other classes and the 'key-' prefix
        var keys = $(this).attr('class').match(/REGEX HERE/);

        // THIS IS WHERE THE CODE GETS A LITTLE MESSY
        // I AM VERY UNSURE ABOUT THE FOLLOWING

        // Define all special characters and set them to false
        var ctrl = false, alt = false, shift = false;

        // First test for special characters
        // Test for ctrl key
        if(keys.indexOf('ctrl')!=-1){
            ctrl = true;
            // Remove ctrl from the keys array
            keys.splice(keys.indexOf('ctrl'),1)
        }
        // Test for alt key
        if(keys.indexOf('alt')!=-1){
            alt = true;
            // Remove alt from the keys array
            keys.splice(keys.indexOf('alt'),1)
        }
        // Test for shift key
        if(keys.indexOf('shift')!=-1){
            shift = true;
            // Remove shift from the keys array
            keys.splice(keys.indexOf('shift'),1)
        }

        // Determine special characters to test for
        if(ctrl&&alt&&shift){

            // Bind the keypress event to the document

            $(document).keypress(function(e) {
                if((e.ctrlKey||e.metaKey)&&e.altKey&&shiftKey) {

                    var continue = true;

                    // Test for other characters in keys array
                    for(var i=0;i<keys.length;i++){

                        // THIS IS WHAT I AM REALLY UNSURE ABOUT
                        if(keys.indexOf(charCodeAt(e.which))==-1){
                            // Correct key was not pressed so do not continue
                            continue = false;
                        }
                    }

                    if(continue){
                        e.preventDefault();
                        // Proceed to triggering the click event
                        // No more help needed from here...
                    }
                }
                return true;
            });
        }else if(ctrl&&alt){

        }else if(ctrl&&shift){

        }else if(shift&&alt){

        }else if(ctrl){

        }else if(alt){

        }else if(shift){

        }
    });
}

上記からわかるように、コードはかなり長い間曲がりくねっていますが、別の書き方がわかりません...あちこちに配列があるいくつかの整理されたものを除いて、それでもネストされたifステートメントはきれいです彼らは大いに必要ではありませんか?

最後に、私の質問

コードがかなり乱雑で、おそらく少し/はるかに良く書くことができるという事実を除いて(これについての見解がある場合はそれらを提供してください)、私の実際の質問は次の行を参照しています:

keys.indexOf(charCodeAt(e.which))==-1

これは、すべてのブラウザで文字コードから文字を取得するための信頼できる方法ですか?そうでない場合、それを行うためのより良い方法はありますか?

コードの残りの部分について意見がある人は、投稿してください。フィードバックをお寄せください。

4

1 に答える 1

1

私がこれを始めたとき、私は全部を書き直すつもりはありませんでした。しかし、私はそうしました、そしてあなたはそれがこのjsfiddleで働いているのを見ることができます。

テクニックは、すべてのターゲット要素を見つけて、それぞれがマップするキーの組み合わせのリストを作成することです。これらを配列keybindingsに格納し、誰かがキーを押すたびに、リスト全体を調べて一致するものを探します。見つかった場合は、要素でクリックイベントをトリガーします。

実際に修飾子情報を取得するため、keydown代わりに使用しました。keypressクラス文字列の解析も改善しましたが、少しすっきりさせることができると思います。

これがJSコードです。

var keybindings = [];

$('[class*="key-"]').each(function (idx, val) {
    var keyspec = {
        which: 0,
        altKey: false,
        shiftKey: false,
        ctrlKey: false,
        element: val
    };

    var keystring = $(val).attr('class').toLowerCase();
    var match = /key-\S+/.exec(keystring);
    var parts = match.toString().split('-');
    keyspec.which = parts[ parts.length-1 ].toUpperCase().charCodeAt(0);
    for (var jdx in parts) {
        if (parts[jdx] == 'alt') keyspec.altKey = true;
        else if (parts[jdx] == 'shift') keyspec.shiftKey = true;
        else if (parts[jdx] == 'ctrl') keyspec.ctrlKey = true;
    }
    keybindings.push( keyspec );
});

$(document).keydown( function(evt) {
    $.each(keybindings, function(idx, oneBind) {
       if (evt.which == oneBind.which
           && evt.altKey == oneBind.altKey
           && evt.shiftKey == oneBind.shiftKey
           && evt.ctrlKey == oneBind.ctrlKey)
           $(oneBind.element).click();
    });
});

もちろん、これにはおそらくjqueryプラグインがすでに存在しているので、それを使用することができます。

于 2013-01-30T04:47:46.883 に答える