这个问题让我把头发撕掉了。AS3 ExternalInterface/navigateToUrl弹出窗口在setTimeout中调用时被阻止
症状:弹出窗口间歇性地阻止/让外部接口和navigateToURL组合通过。
问题:Flash(或浏览器..不确定)不会让弹出窗口在时间范围和/或事件持续时间之外被触发。
环境:我有一个应用程序需要通过zendAMF发送数据,做一些处理并发送回Flash播放器。在回应中,如果某些条件符合条件,则触发一个弹出窗口。响应中阻止的相同代码直接来自鼠标事件触发器。
所以我设置了一个基本的情况:6个按钮,调用3个方法。 3个按钮会直接调用该方法(完全打开该窗口),其他三个按钮将获得数字步进器的值,并使用setTimeout(openWinMethod,NumericStepper.value)模拟来自zendAMF响应的延迟调用。
更新:如果我先选择'navigateToURL,无延迟'按钮,关闭该窗口,然后尝试其他任何延迟调用 - 它们的工作。它就像浏览器接受你点击某个时候打开一个窗口,因此被允许从一个延迟然后打电话。 (firefox only)
所有三个使用延迟将被阻止(firefox和chrome),而所有三个直接打开。 野生动物园 - 为有据可查的,只会使用的navigateToUrl
有趣的 2种方法工作:在HTML包装的js函数将被称为是外部接口打开了一扇窗。毫不拖延地工作。随着延迟,js函数将被调用(通过一些警报语句验证),但新窗口从未产生。
我面临两个选择: 1 - 更改过程以要求用户点击以继续,一旦我收到我对zenAMF的响应,或者找到原因并解决它的原因(优选)
演示可以在这里找到:http://www.digital.leskiwis.com/as3/popup/
这里是我的AS3类:
package
{
import fl.controls.Button;
import fl.controls.NumericStepper;
import flash.display.Sprite;
import flash.events.*;
import flash.text.TextField;
import flash.utils.*;
import flash.net.*;
import flash.external.ExternalInterface;
public class Main extends Sprite
{
private var but1:Button;
private var but2:Button;
private var but3:Button;
private var but4:Button;
private var but5:Button;
private var but6:Button;
private var reporting:TextField;
private var dlay:NumericStepper;
private var url:String = 'http://www.google.com';
private var target:String = "_blank";
public function Main()
{
if (stage) init();
else addEventListener(Event.ADDED_TO_STAGE, init);
}
private function init(e:Event = null):void
{
removeEventListener(Event.ADDED_TO_STAGE, init);
// entry point
dlay = new NumericStepper()
dlay.minimum = 0
dlay.maximum = 5
dlay.stepSize = 0.1
addChild(dlay)
but1 = new Button()
but1.label = "External interface window.open, use delay"
but1.addEventListener(MouseEvent.CLICK, onOpenDelay, false, 0, true);
addChild(but1)
but1.width = 300
but1.y = 50;
but2 = new Button()
but2.label = "External interface window.open, no delay"
but2.addEventListener(MouseEvent.CLICK, onOpen, false, 0, true);
addChild(but2)
but2.width = 300
but2.y = 80;
but5 = new Button()
but5.label = "External interface JS, use delay"
but5.addEventListener(MouseEvent.CLICK, onJSOpenDelay, false, 0, true);
addChild(but5)
but5.width = 300
but5.y = 110;
but6 = new Button()
but6.label = "External interface JS, no delay"
but6.addEventListener(MouseEvent.CLICK, onJSOpen, false, 0, true);
addChild(but6)
but6.width = 300
but6.y = 140;
but3 = new Button()
but3.label = "Navigate to url, use delay"
but3.addEventListener(MouseEvent.CLICK, onNavUrlDelay, false, 0, true);
addChild(but3)
but3.width = 300
but3.y = 170;
but4 = new Button()
but4.label = "Navigate to url, no delay"
but4.addEventListener(MouseEvent.CLICK, onNavUrl, false, 0, true);
addChild(but4)
but4.width = 300
but4.y = 200;
reporting = new TextField;
reporting.y = 230
reporting.width = 300;
reporting.height = 170
addChild(reporting);
}
private function onOpen(e:MouseEvent = null):void {
ExternalInterface.call('window.open',url, 'myWin','height=700,width=900,toolbar=no,scrollbars=yes');
tracer('opening window with window.open')
}
private function onOpenDelay(e:MouseEvent):void {
tracer(('opening window in ' + dlay.value + ' seconds...'))
setTimeout(onOpen, dlay.value * 1000)
}
private function onJSOpen(e:MouseEvent = null):void {
tracer('opening window with external js function ...')
var success : Boolean = ExternalInterface.call("openURL", url, target);
if (!success) tracer('pop up blocked..');
}
private function onJSOpenDelay(e:MouseEvent):void {
tracer(('opening js external in ' + dlay.value + ' seconds...'))
setTimeout(onJSOpen, dlay.value * 1000)
//setTimeout(function():void { ExternalInterface.call("openURL", url, target); }, dlay.value * 1000)
}
private function onNavUrl(e:MouseEvent = null):void {
tracer('opening with navigateToURL')
try {
navigateToURL(new URLRequest(url), '_blank');
} catch (e:Error) {
tracer("Error occurred! " + e);
}
}
private function onNavUrlDelay(e:MouseEvent):void {
tracer(('opening navigateToURL in ' + dlay.value + ' seconds...'))
setTimeout(onNavUrl, dlay.value * 1000)
//setTimeout(function():void { navigateToURL(new URLRequest(url), '_blank'); }, dlay.value * 1000)
}
private function tracer(msg:String):void {
trace(msg)
reporting.appendText(msg + '\n');
}
}
}
这里是HTML:
<!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>popup test</title>
<meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1" />
<script script language='JavaScript' type='text/javascript'>
function openURL(url, target)
{
try
{
var popup = window.open(url, target);
if (popup == null)
return false;
if (window.opera)
if (!popup.opera)
return false;
}
catch(err)
{
alert('errr...');
return false;
}
return true;
}
</script>
<script type="text/javascript" src="js/swfobject.js"></script>
<script type="text/javascript">
var flashvars = {};
var params = {wmode:"opaque",allowScriptAccess:"always"};
//var params = {allowScriptAccess:"sameDomain"};
var attributes = {};
attributes.id = "popupTest";
attributes.name = "popupTest";
swfobject.embedSWF("swf/popup2.swf", "altContent", "400", "400", "9.0.0", "swf/expressInstall.swf", flashvars, params, attributes);
</script>
</head>
<body>
<div id="altContent">
</div>
</body>
</html>
似乎在顶部打开一个新窗口,只有在条件满足false时才必须关闭它。此外,它不解释为什么使用externalInterface和navigatetoURL操作与交互事件将使所有后续调用可用于延迟设置。 但它看起来像我将不得不在另一个用户确认过程中的某个地方工作。感谢您的链接 – Beans 2010-09-20 09:22:30
从Flash 10开始,有几件事情受到了限制。与下载,上传功能相同。如果触发核心的事件是用户交互(鼠标单击或键盘事件),则可以使用此功能。我认为如果没有这个,我们会淹没成千上万的弹出窗口,自动从愚蠢的Flash添加开启。 – 2012-07-30 12:54:50