4

可能重复:
如何使 flex 仅在有用时使用鼠标滚动和键盘事件,否则将其传递给浏览器?

我正在制作一个支持热键的 Web 应用程序,但该应用程序以 justin.tv 流嵌入的形式大量使用了 Flash。我担心一旦用户按下播放或停止或以任何其他方式聚焦闪存字段,它会在它们到达 Javascript 之前吃掉所有后续的关键事件。我很担心,因为我知道 YouTube flash 字段会这样做;一旦聚焦,我无法使用 CTRL+W 或 CTRL+Tab 关闭浏览器窗口进入另一个选项卡。

这是 YouTube Flash 播放器独有的吗?如果没有,我可以在 Javascript 方面做些什么来确保专注于我的应用程序,让我的热键起作用?

任何有关 Javascript 关键事件和浏览器插件主题的其他信息将不胜感激。

PS:我知道我可以通过不可见的 div 覆盖完全拒绝对 Flash 字段的访问,但我希望允许任何用户播放/停止和控制嵌入流的音量。

4

2 回答 2

1

此解决方案仅在 Windows 上的 Firefox 上进行了测试。

主要问题似乎是从 Flash 中删除键盘焦点。将焦点放在Flash上已经有一些关于 SO 的解决方案

经过一番玩弄,我发现使用 jQuery(最新),您可以将焦点直接指向表单的文本框,它将从 Flash 中获取键盘输入的控制权。解决方案遵循以下过程:

  • ExternalInterface在 Flash 中向 javascript 发送命令
  • Javascript(在此示例中使用 jQuery)将焦点设置到表单文本字段
  • Javascript 从 Flash 中移除焦点(使用此 SO 方法获取 Flash 对象)

这是AS3代码。(我在 Flash IDE 中进行了设置,因此如果使用外部 AS3 文件,则必须对其进行调整):

import flash.events.KeyboardEvent;

stage.addEventListener(KeyboardEvent.KEY_DOWN, displayKey);

function displayKey(keyEvent:KeyboardEvent) {
    /* You can use this commented code for limiting the keys that change focus. */
    /*
    var modifier:String="";
    var keyPressed:String="";

    if (keyEvent.ctrlKey) {
        modifier="Ctrl + ";
    } else if (keyEvent.altKey) {
        modifier="Alt + ";
    } else if (keyEvent.shiftKey) {
        modifier="Shift + ";
    }

    keyPressed=keyEvent.keyCode.toString();

    // make sure to add a textfield to the stage, and name it "myTextField" to make this line work:
    myTextField.text= modifier + keyPressed;
    */

    if (ExternalInterface.available) {
        // Limit the keystrokes using javascript by using this method: 
        // ExternalInterface.call("sendToJavaScript", modifier + keyPressed );

        // Any keystroke will unfocus:
        ExternalInterface.call("sendToJavaScript", "");
    }
}

示例 HTML/Javascript 代码如下;您将需要swfobject.js在同一目录中的文件。请注意,Flash 元素的 id 是 Fl​​ash IDE 的默认值,文本输入的 id 是text1.

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
<html xmlns="http://www.w3.org/1999/xhtml" lang="en" xml:lang="en">
    <head>
        <title>testFocus</title>
        <meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
        <style type="text/css" media="screen">
            html, body { height:100%; background-color: #ffffff;}
            body { margin:0; padding:0; }
            #flashContent { width:100%; height:100%; }
            .focus {
                border: 10px solid #00ffff;
                background-color: #ff0000;
            }
        </style>

        <script type="text/javascript" src="http://code.jquery.com/jquery-latest.min.js" charset="utf-8"></script>
    </head>
    <body>
        <div id="outerdiv"><form id="form1">
        <input type="text" value="hmmm" id="text1">test</input>
        </form>
        </div>
<div id="flashContent">
            <object classid="clsid:d27cdb6e-ae6d-11cf-96b8-444553540000" width="1024" height="768" id="testFocus" align="middle">
                <param name="movie" value="testFocus.swf" />
                <param name="quality" value="high" />
                <param name="bgcolor" value="#0033ff" />
                <param name="play" value="true" />
                <param name="loop" value="true" />
                <param name="wmode" value="window" />
                <param name="scale" value="showall" />
                <param name="menu" value="true" />
                <param name="devicefont" value="false" />
                <param name="salign" value="" />
                <param name="allowScriptAccess" value="sameDomain" />
                <!--[if !IE]>-->
                <object type="application/x-shockwave-flash" data="testFocus.swf" width="1024" height="768">
                    <param name="movie" value="testFocus.swf" />
                    <param name="quality" value="high" />
                    <param name="bgcolor" value="#0033ff" />
                    <param name="play" value="true" />
                    <param name="loop" value="true" />
                    <param name="wmode" value="window" />
                    <param name="scale" value="showall" />
                    <param name="menu" value="true" />
                    <param name="devicefont" value="false" />
                    <param name="salign" value="" />
                    <param name="allowScriptAccess" value="sameDomain" />
                <!--<![endif]-->
                    <a href="http://www.adobe.com/go/getflash">
                        <img src="http://www.adobe.com/images/shared/download_buttons/get_flash_player.gif" alt="Get Adobe Flash player" />
                    </a>
                <!--[if !IE]>-->
                </object>
                <!--<![endif]-->
            </object>
        </div>

    <script language="JavaScript">

         $(document).ready(function() {

            // just for kicks:
            $('#text1').blur(function(){
                $(this).removeClass("focus");
            });

            // handles form's text input focus (referenced by element's id):
            $('#text1').focus(function() {
                //alert('Handler for .focus() called.');
                $(this).addClass("focus");
                removeFocusOnFlash();
            });

        });

        function removeFocusOnFlash() {

            // Find the Flash container:
            var f = $('#flashContent');

            if (f) { 
                // Hide flash:
                f.tabIndex = 0; 
                f.blur();

                f.removeClass("focus");
            }
        }

        // This is called by the Flash file:
        function sendToJavaScript(value) {

            // set focus on the form's text input field: 
            $('#text1').focus();
        }
    </script>
 </body>
</html>
于 2012-04-24T19:01:06.190 回答
0

除非通过用户交互激活 Flash,否则它不会接收键事件。但是,一旦发生,它就不会将关键事件重新传输到 DOM。不幸的是,即使您可以在 JavaScript 中捕获所有键,通常也无法在您选择时通知 Flash。Flash 也不会通过选项卡获得焦点,但是一旦获得焦点,就不会将其转移回页面。只有某些组合键是您在 Flash 中听不到的(因为它们是由浏览器处理的),例如 Ctrl+O。

但是,如果您可以控制在 Flash 中执行的代码(至少,您必须能够将外部 SWF 加载到您自己的 SWF 中),那么您可以将击键传递给它并从中传递。我不确定制表位。我认为这取决于浏览器以及它是否允许 JavaScript 调用focus().

这是一个演示,它仅适用于鼠标右键单击,但对于其他键/鼠标事件也类似。

于 2012-04-23T10:46:50.753 回答