AS3 管理快捷键类 (Shortcut)

最近开发的一个项目要用到单键快捷键, 遂写了个快捷键管理类.

目前能满足需求, 使用方便, 开放出来, 欢迎大家拍砖 :D

主要功能:

  1. 各快捷键可对应多个方法
  2. 各快捷键可分别绑定 KeyUp 或 KeyDown 事件
  3. 已"快捷键+事件+方法"确定某绑定, 均可单独注册/反注册

下面是代码 (Shortcut.as) :
package com.douban.utils
{
    import flash.display.Stage;
    import flash.events.KeyboardEvent;
    
    /**
     * 快捷键管理器
     * @author Seven Yu
     */
    public class Shortcut
    {
        
        // 注册/注销快捷键动作
        private static const ACTION_ADD:int = 1;
        private static const ACTION_DEL:int = -1;
        
        // 保存按键与方法映射
        private static var _keyMaps:Object = {};
        
        // 绑定键盘监听的 stage
        private static var _stage:Stage;
        
        // 是否开始监听标记 (可以暂停全部监听, 改造成非静态类可以按需暂停/监听)
        private static var _started:Boolean = false;
        
        // 事件类型对应方法计数器
        private static var _upFuncsCount:int = 0;
        private static var _downFuncsCount:int = 0;
        
        /**
         * 初始化
         * @param	stage     绑定键盘事件的 stage
         * @param	autoStart 自动开始监听 (默认: false)
         */
        public static function init(stage:Stage, autoStart:Boolean = false):void
        {
            _stage = stage;
            autoStart && start();
        }
        
        /**
         * 开始监听键盘事件
         */
        public static function start():void
        {
            if (_stage)
            {
                _started = true;
            }
        }
        
        /**
         * 停止监听
         */
        public static function stop():void
        {
            _started = false;
        }
        
        
        /**
         * 处理快捷键响应
         * @param	evt
         */
        private static function keyHandler(evt:KeyboardEvent):void
        {
            trace('event type:', evt.type, 'key code:', evt.keyCode);
            if (!_started)
            {
                return;
            }
            var keyName:String = getKeyName(evt.type, evt.keyCode);
            if (keyName in _keyMaps)
            {
                var funcs:Array = _keyMaps[keyName].concat();
                for (var i:int = 0, len:int = funcs.length; i < len; i++)
                {
                    funcs[i]();
                }
            }
        }
        
        /**
         * 注册快捷键
         * @param	keyCode
         * @param	func
         * @param	type
         */
        public static function register(keyCode:int, func:Function, type:String = KeyboardEvent.KEY_UP):void
        {
            trace('shortcat.register', keyCode);
            var keyName:String = getKeyName(type, keyCode);
            if (keyName in _keyMaps)
            {
                trace(_keyMaps[keyName].indexOf(func));
                if (_keyMaps[keyName].indexOf(func) == -1)
                {
                    _keyMaps[keyName].push(func);
                    checkFuncs(type, ACTION_ADD);
                }
            }
            else
            {
                _keyMaps[keyName] = [func];
                checkFuncs(type, ACTION_ADD);
            }
        }
        
        /**
         * 注销快捷键
         * @param	keyCode
         * @param	func
         * @param	type
         */
        public static function unregister(keyCode:int, func:Function, type:String = KeyboardEvent.KEY_UP):void
        {
            trace('shortcat.unregister', keyCode);
            var keyName:String = getKeyName(type, keyCode);
            if (keyName in _keyMaps)
            {
                var funcIndex:int = _keyMaps[keyName].indexOf(func);
                if (funcIndex >= 0)
                {
                    _keyMaps[keyName].splice(funcIndex, 1);
                    checkFuncs(type, ACTION_DEL);
                }
            }
        }
        
        /**
         * 检测函数注册数, 以确定绑定或移除事件监听
         * @param	type   事件类型
         * @param	action 动作(添加或移除)
         */
        private static function checkFuncs(type:String, action:int):void
        {
            trace('check funcs', type, action);
            if (!_stage)
            {
                throw new Error('Please call Shortcut.init method first.');
            }
            switch (type)
            {
                case KeyboardEvent.KEY_UP: 
                {
                    _upFuncsCount += action;
                    if (1 == _upFuncsCount)
                    {
                        _stage.addEventListener(KeyboardEvent.KEY_UP, keyHandler);
                    }
                    if (0 == _upFuncsCount)
                    {
                        _stage.removeEventListener(KeyboardEvent.KEY_UP, keyHandler);
                    }
                    break;
                }
                case KeyboardEvent.KEY_DOWN: 
                {
                    _downFuncsCount += action;
                    if (1 == _downFuncsCount)
                    {
                        _stage.addEventListener(KeyboardEvent.KEY_DOWN, keyHandler);
                    }
                    if (0 == _downFuncsCount)
                    {
                        _stage.removeEventListener(KeyboardEvent.KEY_DOWN, keyHandler);
                    }
                    break;
                }
                default: 
                {
                    throw new Error('KeyboardEvent.KEY_UP & KeyboardEvent.KEY_DOWN only.');
                    break;
                }
            }
        }
        
        /**
         * 获取映射名
         * @param	type    事件类型
         * @param	keyCode 按键键值
         * @return  形如 type_keyCode 的字符串
         */
        private static function getKeyName(type:String, keyCode:int):String
        {
            return [type, keyCode].join('_');
        }
        
        /**
         * 是否已开始监听
         */
        static public function get started():Boolean
        {
            return _started;
        }
    }
}

例: (伪代码)
// 初始化快捷键管理器
Shortcut.init(stage, true);

// 注册 空格 + KeyUp + testFunc1 (默认 KeyUp 事件)
Shortcut.register(Keys.SPACEBAR, testFunc1);

// 注册 空格 + KeyDown + testFunc1
Shortcut.register(Keys.SPACEBAR, testFunc1, KeyboardEvent.KEY_DOWN);

// 注册 S + KeyUp + testFunc2
Shortcut.register(Keys.S, testFunc2, KeyboardEvent.KEY_UP);

// 反注册 空格 + KeyUp + testFunc1 (KeyUp 为默认值, 可省略)
Shortcut.unregister(Keys.SPACEBAR, testFunc1, KeyboardEvent.KEY_UP);

// 反注册 E + KeyUp + testFunc2 (不会有任何反映, 该组合没被注册过)
Shortcut.unregister(Keys.E, testFunc2);

// 测试函数1
private function testFunc1():void
{
    trace('test function 1');
}

// 测试函数2
private function testFunc2():void
{
    trace('test function 2');
}

另外代码中还用到一个 Keys 类, 是对一些键位相应 KeyCode 常量的定义, 直接改成对应的数字即可, 例如: 空格->32,  S->83, E->69

可能还有不成熟的地方, 欢迎拍砖, 共同探讨 :D

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值