在我的网站上嵌入Flash对象会成为Javascript关键事件的问题吗?
Will Flash object embeds on my website be an issue for Javascript key events?
可能的重复项:
如何使 flex 仅在有用时才使用鼠标滚动和键盘事件,否则将其传递给浏览器?
我正在制作一个支持热键的 Web 应用程序,但该应用程序以 justin.tv 流嵌入的形式大量使用闪存。我担心一旦用户按下播放或停止或以任何其他方式聚焦闪存场,它将在到达Javascript之前吃掉所有后续关键事件。我很担心,因为我知道 YouTube Flash 字段会这样做;一旦它聚焦,我就无法使用 CTRL+W 或 CTRL+Tab 关闭浏览器窗口到另一个选项卡。
这是YouTube闪存播放器独有的吗?如果没有,我可以在 Javascript 方面做些什么来确保专注于我的应用程序,让我的热键发挥作用?
有关Javascript密钥事件和浏览器插件主题的任何其他信息将不胜感激。
PS:我知道我可以通过不可见的div覆盖完全拒绝对Flash字段的访问,但是我希望允许任何用户播放/停止并控制嵌入式流的音量。
此解决方案仅在Windows上的Firefox上进行了测试。
主要问题似乎是从Flash中删除键盘焦点。 将焦点设置为闪存已经在SO上提供了一些解决方案。
经过一番尝试,我发现使用jQuery(最新),您可以将焦点指向表单的文本框,这将从Flash获得对键盘输入的控制权。 解决方案遵循以下过程:
- Flash 中的
ExternalInterface
向 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 是 Flash 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>
除非通过用户交互激活 Flash,否则它不会接收关键事件。但是,一旦发生,它不会将密钥事件重新传输到 DOM。 不幸的是,即使你可以在 JavaScript 中捕获所有密钥,你通常也无法在选择时通知 Flash。Flash 也不会通过制表符接收焦点,但一旦获得焦点,就不会将其传输回页面。只有某些组合键不能在 Flash 中收听(因为它们由浏览器处理),例如 Ctrl+O。
但是,如果您可以控制在Flash中执行的代码(至少,您必须能够将外部SWF加载到您自己的SWF中),那么您可以将击键传递给它以及从它传递击键。我不确定制表符。我认为这取决于浏览器以及它是否允许 JavaScript 调用focus()
.
这是一个演示,它仅适用于鼠标右键单击,但对于其他键/鼠标事件也类似。
- 如何将javascript事件从web浏览器wpf控件发送到wpf的c#代码
- 在同一个javascript事件处理程序中调用不同的函数
- Javascript事件;在新选项卡中打开”;
- 存在每个时间元素的javascript事件
- Javascript事件.锚的目标问题
- 带有参数的Javascript事件处理程序
- 如何从另一个处理程序内部取消JavaScript事件处理程序函数的执行
- firefox中的Javascript事件范围问题
- Firefox中的JavaScript事件参数
- 在动态加载的PHP表单上放置JavaScript事件
- 如何在Javascript事件上从JSNI设置GWTClass字段
- Javascript事件发射器一次处理多个事件
- 在下拉式javascript事件监听器中选择时触发事件
- 在javascript中导入xlsx文件时,如何手动强制javascript事件
- 显示触发的JavaScript事件
- 正在取消IE11中的JavaScript事件
- 页面卸载期间的JavaScript事件循环
- 存在其他参数时访问Javascript事件
- 阻止Javascript事件影响子元素
- 如何在事件处理程序中获取 javascript 事件对象