Flex的组合键监听功能实现
最近在用Flex做一个绘图软件,需要实现复制/黏贴/删除图形的功能,一般用户习惯于使用Ctrl+C/Ctrl+V来复制黏贴,使用Delete键来删除,删除功能容易做,监听Stage的键盘按下事件就可以了,但监听Ctrl+C/V 对Flex来说成为了问题,因为Flex的监听机制,一旦按下了Ctrl键就监听不到其他键按下的事件了,即按下了Ctrl后Flex无法检测到其他键按下。要想实现Ctrl+C/V组合键,只能通过JS来监听了。 这涉及到2个问题: 1.Flex和JS的通信。 2.html页面的焦点。因为焦点在swf上时js无法监听到任何事件,所以当我们需要监听复制/黏贴事件时,需要把页面焦点设置为window。 代码如下: Flex部分代码(类名KeyboardManager.as): initialize()函数的参数stage是Applicatoin的舞台,KeyboradManager.as类初始化时调用这个函数。 ExternalInterface.addCallback("name",func);语句的意思是,当js使用Applicatoin.name语句时,Flex端就调用函数func。说简单些就是为js的注册一个回调函数func。 private var keysDown:Object = new Object(); ??? ?// 已按下的键的队列 public function initialize( stage:Stage ) : void { ExternalInterface.addCallback("keyDown",onKeyDown); ExternalInterface.addCallback("keyUp",onKeyUp); stage.addEventListener(KeyboardEvent.KEY_DOWN,swfKeyDown); } public function onKeyDown( keyCode:uint ) : void { ?? ??? keysDown[keyCode] = true;?? ? ?? ??? ?checkKeyRole(keyCode); ?} ?? ??? ? ?public function onKeyUp( keyCode:uint ) : void { ?? ??? if (keyCode in keysDown) { ?? ??? delete keysDown[keyCode]; ?? ??? } } public function swfKeyDown( e:KeyboardEvent ) : void { ?? ??? ??? ?var focus:Object = mx.core.Application.application.focusManager.getFocus(); ?? ??? ??? ? ?? ??? ??? ?if( e.keyCode == Keyboard.CONTROL ){ ?? ??? ??? ??? ?//当焦点在输入框时用户可能需要复制/黏贴文本,所以不向js发送获取焦点请求。js获取焦点后会拦截键盘输入使windows的复制黏贴功能失效。 ?? ??? ??? ??? ?if( !(focus is TextInput) ){ ?? ??? ??? ??? ??? ?ExternalInterface.call("setFocus"); ?? ??? ??? ??? ?}?? ? ?? ??? ??? ??? ??? ? ?? ??? ??? ??? ?onKeyDown(e.keyCode); ?? ??? ??? ?}else if( e.keyCode == Keyboard.DELETE ){ ?? ??? ??? ??? ?onKeyDown(e.keyCode); ?? ??? ??? ?} } /** * 检测按下的键是否有快捷键功能 */ private function checkKeyRole(keyCode:uint) : void { ?? ??? ??? ?switch(keyCode){ ?? ??? ??? ??? ?case Keyboard.C: ?? ??? ??? ??? ??? ?if(isDown(Keyboard.CONTROL)){ ?? ??? ??? ??? ??? ??? ?//TODO:复制图形 ?? ??? ??? ??? ??? ?} ?? ??? ??? ??? ??? ?break; ?? ??? ??? ??? ?case Keyboard.V: ?? ??? ??? ??? ??? ?if(isDown(Keyboard.CONTROL)){ ?? ??? ??? ??? ??? ??? //TODO:黏贴图形 ?? ??? ??? ??? ??? ?} ?? ??? ??? ??? ??? ?break; ?? ??? ??? ??? ?case Keyboard.DELETE: ?? ??? ??? ??? ??? ?//TODO:删除图形 ?? ??? ??? ??? ??? ?break;?? ??? ??? ??? ? ?? ??? ??? ?} } /* * 判断某颗键有没有按下 */ public function isDown(keyCode:uint):Boolean { ?? ??? ??? ?return Boolean(keyCode in keysDown); } js代码: document.onkeydown = func,即为html页面添加键盘监听事件 ${application}.name(arg),即调用Flex端注册的回调函数,${application}是Flex编译生成的swf的名字。 document.onkeydown = onKeyDown; document.onkeyup = onKeyUp; function onKeyDown(){ var code = window.event.keyCode; ${application}.keyDown(code); } function onKeyUp(){ var code = window.event.keyCode; ${application}.keyUp(code); } function setFocus(){ window.focus(); } 我们从swfKeyDown函数开始跟踪一下组合键监听的思路。 1.当用户有键盘动作时,首先被swfKeyDown函数捕获到(因为此时页面的焦点必然在swf上)。 2.swfKeyDown捕获到键盘事件后判断按下的是什么键,如果是delete键,则不需要使用js监听组合键,直接调用onKeyDown函数做相应处理。 3.如果按下的Ctrl键,判断此时swf系统的焦点,如果焦点在TextInput组件上,则用户肯定是要复制文字,我们不做处理。当系统焦点没有在TextInput组件上而用户按下了Ctrl 键,那他必然需要复制图形,这时候我们调用js的函数setFoces()将焦点置回html页面,这时候js的键盘监听生效了。 4.swfKeyDown函数调用onKeyDown函数,swfKeyDown将Ctrl键放入键队列keysDown. 5.当用户再次按下C/V键时,被js的onKeyDown函数捕获,然后调用Flex端的onKeyDown函数 6.onKeyDown调用checkKeyRole函数,带有参数 keyCode 7.checkKeyRole根据keyCode判断此时用户按下的键是C/V,然后调用isKeyDown()判断Ctrl键是否被按下 8.若isKeyDown返回true,则做复制/黏贴图形的操作;若isKeyDown返回false,则不做任何操作。 (编辑:李大同) 【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容! |