使用wmode =“transparent”触发的两个KeyboardEvent.KEY_DOWN事件

时间:2009-12-22 16:38:30

标签: flex actionscript-3

当我使用wmode =“transparent”侦听按键和按键事件时,我会收到2个按键事件,然后是以下按键的单个按键事件:F键,箭头键,ins,del,home ,结束,向上翻页,向下翻页,暂停,打印屏幕,应用程序键,Windows键和等效的数字小键盘键。其他键正常工作。这种情况发生在FF 3.5中,但不适用于IE 6。

下面是一个简单的Flex应用程序,它说明了使用wmode =“transparent”运行它时的问题。

<?xml version="1.0" encoding="utf-8"?>
<mx:Application xmlns:mx="http://www.adobe.com/2006/mxml" layout="absolute" applicationComplete="init()">
<mx:Script>
 <![CDATA[
 import mx.controls.Label;
 private function init():void {
  stage.addEventListener(KeyboardEvent.KEY_DOWN, onKey);
  stage.addEventListener(KeyboardEvent.KEY_UP, onKey);
 }
 private function onKey(event:KeyboardEvent):void {
  var msg:Label = new Label();
  msg.text = event.toString();
  eventLog.addChildAt(msg, 0);
 }
]]>
</mx:Script>
<mx:VBox width="100%" height="100%">
 <mx:TextInput width="100%" text="Hello"/>
 <mx:VBox id="eventLog" width="100%" height="100%"/>
</mx:VBox>
</mx:Application>

我们的应用程序需要wmode =“transparent”,并且需要为有问题的键处理key up和key down事件,所以我正在寻找解决此问题的最佳方法。这个问题最好的解决方法是什么?我可以使用一些Flash播放器参数来使其正常工作吗? (FF配置更改对我们的应用程序不可行,但可能有助于理解其原因。)

2 个答案:

答案 0 :(得分:1)

顺便说一句,我目前支持的解决方法是在初始按键事件发生后的短暂死区(可能是50-100毫秒)内丢弃密钥的其他按键事件。该解决方案的优点是实现起来相对简单,同时仍然支持密钥重复,但在重复开始之前会有额外的延迟。

这基本上是我添加到测试代码中的内容:

private var keyDownTs:Array = new Array();

private function onKey(event:KeyboardEvent):void {
    var msg:Label = new Label();
    msg.text = getTimer() + "-" + (isDead(event) ? "**DEAD**" : "") + event.toString();
    eventLog.addChildAt(msg, 0);
}

private function isDead(event:KeyboardEvent):Boolean {
    var dead:Boolean = false;
    switch (event.type) {
        case KeyboardEvent.KEY_DOWN:
            var ts:int = keyDownTs[event.keyCode];
            if (ts == 0) {
                // save timestamp for the initial key down event
                keyDownTs[event.keyCode] = getTimer();
            } else if (getTimer() - ts < 50) {
                // this key down is within the dead-band of the initial key down
                dead = true;
            }
            break;
        case KeyboardEvent.KEY_UP:
            // clear previous key down timestamp
            keyDownTs[event.keyCode] = 0;
            break;
    }
    return dead;
}

在我的系统上,虚假按键事件发生在初始按键下降(2-6 ms)的几毫秒内,因此50 ms看起来非常好。对于我的生产实现,我想我会把这个逻辑放到一个EventDispatcher中,KeyboardEvent监听器将使用它而不是直接监听这个阶段。

答案 1 :(得分:0)

我没有给你答案,但可以确认wmo​​de =“transparent”导致与our website上的项目完全相同的行为。使用透明和不透明的wmodes导致这种未识别的(直到现在)双键按压行为。由于不透明和透明模式存在诸多问题,我们改为解决使用标准模式的所有其他问题,因为它是键盘IO正常工作的唯一模式。

其他问题包括错误的键映射,屏幕阅读/辅助功能软件问题,Flash影片在滚动到视口中之前不会开始执行。

如果你有任何办法可以在没有wmode透明的情况下生存,那么请考虑一下,因为否则,就我所见,一切都被堵塞了。

我们最初选择透明模式的原因是我们可以在Flash电影上覆盖其他HTML元素。相反,如果我们要覆盖,我们会“隐藏”闪光灯:

不要使用css display:none,因为这会重置电影(但不会在IE中使用AX版本)。 可以通过css将其高度设置为0.001px,或者通过隐藏在css或两者中隐藏可见性来隐藏电影。