ホームページ  >  記事  >  ウェブフロントエンド  >  jQueryベースのキーボードイベントリスニング制御の紹介(コード例)

jQueryベースのキーボードイベントリスニング制御の紹介(コード例)

不言
不言転載
2019-04-04 09:15:041773ブラウズ

この記事では、jQuery ベースのキーボード イベント リスニング コントロール (コード例) を紹介します。一定の参考価値があります。必要な友人は参照してください。お役に立てば幸いです。

最近のプロジェクトでは、元に戻す、やり直し、移動、ズームなどの操作を実行するためにキーボード イベントを監視する必要がある描画ボードを作成したいと考えたので、キーボード イベント監視コントロールを簡単に実装しました。 、その過程で少し得たものを整理してみましたので、皆様のお役に立てれば幸いです、また専門家のアドバイスも頂ければ幸いです。

1. 自動的にフォーカスを取得する

ブラウザのキーボード イベントは、フォーカスを取得できる要素をリッスンするようにのみ設定できるようで、通常はイベント

、<をリッスンする必要があります。 ;CANVAS> フォーカスを取得できる要素はないため、フォーカスを取得できるようにターゲット要素のプロパティを変更する必要があります。もう 1 つの可能な方法は、イベントを などのタグに委任することです。ここでは最初のタイプのメソッドが使用されます。もちろん、変更できる属性は複数あります。たとえば、

タグの場合、その "editable" 属性を true に設定できますが、ここで使用されるのはtabindex 値を設定することです。コードは次のとおりです:

$ele.attr('tabindex', 1);

また、フォーカス イベントのトリガーには要素のクリックや TAB の切り替えが必要であり、人間の直感とは一致しないため、マウスの動きを監視する必要があります。 -in イベントにより、ターゲット要素が「自動的に」フォーカスを取得できるようになります:

$ele.on('mouseenter', function(){
    $ele.focus();
});

2. キーボード イベントをリッスンする

顧客がプロジェクトで使用するブラウザは主に Chrome (実際には 36x) であるため、 jQuery のイベント監視のみが使用されます:

        $ele.on('keydown', this._keyDownHandler.bind(this));

実装はコントロール指向であるため、キーボード アクションに応答するプライベート メソッド _keyDownHandler が定義されています。

3. キー イベント スクリーニング

jQuery イベント リスナーは多くのイベント オブジェクト情報を返すため、スクリーニングする必要があります。この目的のために、キーの押下を処理するプライベート メソッド _keyCodeProcess が定義されています

function _keyCodeProcess(e){
        var code = e.keyCode + '';
        var altKey = e.altKey;
        var ctrlKey = e.ctrlKey;
        var shiftKey = e.shiftKey;

        var threeKey = altKey && ctrlKey && shiftKey;
        var ctrlAlt = altKey && ctrlKey;
        var altShift = altKey && shiftKey;
        var ctrlShift = shiftKey && ctrlKey;

        var keyTypeSet = this.keyTypeSet;
        var resStr = '';

        if(threeKey){
            resStr = keyTypeSet.threeKey[code];
        } else if(ctrlAlt) {
            resStr = keyTypeSet.ctrlAlt[code];
        } else if(ctrlShift) {
            resStr = keyTypeSet.ctrlShift[code];
        } else if(altShift) {
            resStr = keyTypeSet.altShift[code];
        } else if(altKey) {
            resStr = keyTypeSet.altKey[code];
        } else if(ctrlKey) {
            resStr = keyTypeSet.ctrlKey[code];
        } else if(shiftKey) {
            resStr = keyTypeSet.shiftKey[code];
        } else {
            resStr = keyTypeSet.singleKey[code];
        }

        return resStr
    };

ここでの keyTypeSet は、Ctrl、Shift、Alt ボタンのさまざまなタイプの組み合わせを格納するルックアップ テーブルに似たオブジェクトです。各組み合わせの下に、キー コードに従ってカスタム イベント タイプ文字列が格納されます。イベント発生時 この文字列は後ほどここから返されます もちろん対応するカスタムイベントがない場合は素直に空文字列が返されます。

4. イベント配布

_keyCodeProcessメソッドは、イベントからイベントタイプを抽出し、リスニングコールバック関数をあらかじめルックアップテーブルコールバックに格納しておき、そのキーを「巧妙に」名前だけにしておきます。カスタム イベント文字列の前に「on」プレフィックスを追加すると、簡単に呼び出すことができます。前述の _keyDownHandler は、このために設計されています:

function _keyDownHandler(e){
        var strCommand = this._keyCodeProcess(e);

        var objEvent = {
            type: '',
            originEvent: e.originEvent
        };

        strCommand && this.callback['on' + strCommand](objEvent);

        return null;
    };

5. イベントのサブスクリプションとサブスクリプション解除

前述のとおり, コールバック関数を保存し、適時に呼び出すので、開発者がコールバック関数をオブジェクト インスタンスに簡単に保存できるように、「サブスクリプション」インターフェイスを公開する必要があります。このため、.bind インターフェイスを定義しました。 ##

function bind(type, callback, description){
        var allType = this.allEventType;
        if(allType.indexOf(type) === -1){
            throwError('不支持改事件类型,请先扩展该类型,或采用其他事件类型');
        }

        if(!(callback instanceof Function)){
            throwError('绑定的事件处理回调必须是函数类型');
        }

        this.callback['on' + type] = callback;

        this.eventDiscibeSet[type] = description || '没有该事件的描述';

        return this;
    };
人間用なので、ついでに型チェックもしてみました。

インターフェイスの「対称性」によれば、サブスクライブとサブスクライブ解除を行うのが最善であるため、.unbind インターフェイスは 1 行のコードのみで定義され、実装は次のようになります。

function unbind(type){
        this.callback['on' + type] = this._emptyEventHandler;

        return this;
    };
6. カスタム イベント タイプの拡張

キーボード イベントの組み合わせは豊富でカラフルです。すべてをコントロールに組み込むと、非常に肥大化します。そのため、開発者は、いくつかの一般的なキーの組み合わせに加えて、キーの組み合わせをカスタマイズし、.extendEventType メソッドを介して返すことができます。文字列:

function extendEventType(config){
        var len = 0;
        if(config instanceof Array){
            len = config.length;
            while(len--){
                this._setKeyComposition(config[len]);
            }
        } else {
            this._setKeyComposition(config);
        }
        return this;
    };
._setKeyComposition は、カスタム キーボード イベントを書き込むために使用されるプライベート メソッドです:

_setKeyComposition(config){
        var altKey = config.alt;
        var ctrlKey = config.ctrl;
        var shiftKey = config.shift;

        var threeKey = altKey && ctrlKey && shiftKey;
        var ctrlAlt = altKey && ctrlKey;
        var altShift = altKey && shiftKey;
        var ctrlShift = shiftKey && ctrlKey;
        var code = config.code + '';

        if(threeKey){
            this.keyTypeSet.threeKey[code] = config.type;
        } else if(ctrlAlt) {
            this.keyTypeSet.ctrlAlt[code] = config.type;
        } else if(ctrlShift) {
            this.keyTypeSet.ctrlShift[code] = config.type;
        } else if(altShift) {
            this.keyTypeSet.altShift[code] = config.type;
        } else if(altKey) {
            this.keyTypeSet.altKey[code] = config.type;
        } else if(ctrlKey) {
            this.keyTypeSet.ctrlKey[code] = config.type;
        } else if(shiftKey) {
            this.keyTypeSet.shiftKey[code] = config.type;
        } else {
            this.keyTypeSet.singleKey[code] = config.type;
        }

        return null;
    };
このようにして、キーボード イベントをリッスンします。以下のように、コントロールが完成しました。 完全な実装コードは次のとおりです。

/**
 * @constructor 键盘事件监听器
 * */
function KeyboardListener(param){
    this._init(param);
}

!function(){
    /**
     * @private {String} param.ele 事件对象选择器
     * */
    KeyboardListener.prototype._init = function _init(param){
        this.$ele = $(param.ele);

        this._initEvents();

        this._initEventType();

        return null;
    };

    /**
     * @private _emptyEventHandler 空白事件响应
     * */
    KeyboardListener.prototype._emptyEventHandler = function _emptyEventHandler(){
        return null;
    };

    /**
     * @private _initEventType 初始化所有初始自定义事件类型
     * */
    KeyboardListener.prototype._initEventType = function _initEventType(){
        var allType = ['up', 'down', 'left', 'right', 'undo', 'redo', 'zoomIn', 'zoomOut', 'delete'];
        var intLen = allType.length;
        this.allEventType = allType;
        this.callback = {};
        this.eventDiscibeSet = {};

        for(var intCnt = 0; intCnt < intLen; intCnt++){
            this.callback[&#39;on&#39; + allType[intCnt]] = KeyboardListener.prototype._emptyEventHandler;
        }

        return null;
    };

    /**
     * @private _initEvents 绑定 DOM 事件
     * */
    KeyboardListener.prototype._initEvents = function _initEvents(){
        var $ele = this.$ele;

        $ele.attr(&#39;tabindex&#39;, 1);

        $ele.on(&#39;mouseenter&#39;, function(){
            $ele.focus();
        });

        $ele.on(&#39;keydown&#39;, this._keyDownHandler.bind(this));

        this.keyTypeSet = {
            altKey: {},
            ctrlAlt: {},
            ctrlKey: {},
            threeKey: {},
            altShift: {},
            shiftKey: {},
            ctrlShift: {},
            singleKey: {}
        };

        // 支持一些内建的键盘事件类型
        this.extendEventType([
            {
                type: &#39;redo&#39;,
                ctrl: true,
                shift: true,
                code: 90
            },
            {
                type: &#39;undo&#39;,
                ctrl: true,
                code: 90
            },
            {
                type: &#39;copy&#39;,
                ctrl: true,
                code: 67
            },
            {
                type: &#39;paste&#39;,
                ctrl: true,
                code: 86
            },
            {
                type: &#39;delete&#39;,
                code: 46
            },
            {
                type: &#39;right&#39;,
                code: 39
            },
            {
                type: &#39;down&#39;,
                code: 40
            },
            {
                type: &#39;left&#39;,
                code: 37
            },
            {
                type: &#39;up&#39;,
                code: 38
            }
        ]);

        return null;
    };

    /**
     * @private _keyDownHandler 自定义键盘事件分发
     * */
    KeyboardListener.prototype._keyDownHandler = function _keyDownHandler(e){
        var strCommand = this._keyCodeProcess(e);

        var objEvent = {
            type: &#39;&#39;,
            originEvent: e.originEvent
        };

        strCommand && this.callback[&#39;on&#39; + strCommand](objEvent);

        return null;
    };

    /**
     * @private _keyCodeProcess 处理按键码
     * */
    KeyboardListener.prototype._keyCodeProcess = function _keyCodeProcess(e){
        var code = e.keyCode + &#39;&#39;;
        var altKey = e.altKey;
        var ctrlKey = e.ctrlKey;
        var shiftKey = e.shiftKey;

        var threeKey = altKey && ctrlKey && shiftKey;
        var ctrlAlt = altKey && ctrlKey;
        var altShift = altKey && shiftKey;
        var ctrlShift = shiftKey && ctrlKey;

        var keyTypeSet = this.keyTypeSet;
        var resStr = &#39;&#39;;

        if(threeKey){
            resStr = keyTypeSet.threeKey[code];
        } else if(ctrlAlt) {
            resStr = keyTypeSet.ctrlAlt[code];
        } else if(ctrlShift) {
            resStr = keyTypeSet.ctrlShift[code];
        } else if(altShift) {
            resStr = keyTypeSet.altShift[code];
        } else if(altKey) {
            resStr = keyTypeSet.altKey[code];
        } else if(ctrlKey) {
            resStr = keyTypeSet.ctrlKey[code];
        } else if(shiftKey) {
            resStr = keyTypeSet.shiftKey[code];
        } else {
            resStr = keyTypeSet.singleKey[code];
        }

        return resStr
    };


    /**
     * @private _setKeyComposition 自定义键盘事件
     * @param {Object} config 键盘事件配置方案
     * @param {String} config.type 自定义事件类型
     * @param {keyCode} config.code 按键的码值
     * @param {Boolean} [config.ctrl] 是否与 Ctrl 形成组合键
     * @param {Boolean} [config.alt] 是否与 Alt 形成组合键
     * @param {Boolean} [config.shift] 是否与 Shift 形成组合键
     * */
    KeyboardListener.prototype._setKeyComposition = function _setKeyComposition(config){
        var altKey = config.alt;
        var ctrlKey = config.ctrl;
        var shiftKey = config.shift;

        var threeKey = altKey && ctrlKey && shiftKey;
        var ctrlAlt = altKey && ctrlKey;
        var altShift = altKey && shiftKey;
        var ctrlShift = shiftKey && ctrlKey;
        var code = config.code + &#39;&#39;;

        if(threeKey){
            this.keyTypeSet.threeKey[code] = config.type;
        } else if(ctrlAlt) {
            this.keyTypeSet.ctrlAlt[code] = config.type;
        } else if(ctrlShift) {
            this.keyTypeSet.ctrlShift[code] = config.type;
        } else if(altShift) {
            this.keyTypeSet.altShift[code] = config.type;
        } else if(altKey) {
            this.keyTypeSet.altKey[code] = config.type;
        } else if(ctrlKey) {
            this.keyTypeSet.ctrlKey[code] = config.type;
        } else if(shiftKey) {
            this.keyTypeSet.shiftKey[code] = config.type;
        } else {
            this.keyTypeSet.singleKey[code] = config.type;
        }

        return null;
    };

    /**
     * @method extendEventType 扩展键盘事件类型
     * @param {Object|Array<object>} config 键盘事件配置方案
     * @param {String} config.type 自定义事件类型
     * @param {keyCode} config.code 按键的码值
     * @param {Boolean} [config.ctrl] 是否与 Ctrl 形成组合键
     * @param {Boolean} [config.alt] 是否与 Alt 形成组合键
     * @param {Boolean} [config.shift] 是否与 Shift 形成组合键
     * */
    KeyboardListener.prototype.extendEventType = function extendEventType(config){
        var len = 0;
        if(config instanceof Array){
            len = config.length;
            while(len--){
                this._setKeyComposition(config[len]);
            }
        } else {
            this._setKeyComposition(config);
        }
        return this;
    };

    /**
     * @method bind 绑定自定义的键盘事件
     * @param {String} type 事件类型 如:['up', 'down', 'left', 'right', 'undo', 'redo', 'delete', zoomIn, 'zoomOut']
     * @param {Function} callback 回调函数,参数为一个自定义的仿事件对象
     * @param {String} description 对绑定事件的用途进行说明
     * */
    KeyboardListener.prototype.bind = function bind(type, callback, description){
        var allType = this.allEventType;
        if(allType.indexOf(type) === -1){
            throwError('不支持改事件类型,请先扩展该类型,或采用其他事件类型');
        }

        if(!(callback instanceof Function)){
            throwError('绑定的事件处理回调必须是函数类型');
        }

        this.callback['on' + type] = callback;

        this.eventDiscibeSet[type] = description || '没有该事件的描述';

        return this;
    };
    /**
     * @method unbind 解除事件绑定
     * @param {String} type 事件类型
     * */
    KeyboardListener.prototype.unbind = function unbind(type){
        this.callback['on' + type] = this._emptyEventHandler;

        return this;
    };
}();
[関連する推奨事項:

jQuery ビデオ チュートリアル ]

以上がjQueryベースのキーボードイベントリスニング制御の紹介(コード例)の詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。

声明:
この記事はsegmentfault.comで複製されています。侵害がある場合は、admin@php.cn までご連絡ください。