2010-09-19 101 views
0

这个问题让我把头发撕掉了。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> 

回答

0

阅读:User Interaction Requirements

你会注意到,在“弹出窗口”这两个ExternalInterface的和的navigateToUrl被列为响应唯一的用户交互。基本上你正在做的事情会被阻塞,如果你正在运行一个耗时过长的脚本。

如果你正在寻找这样的事情,那么id要么使用ExternalInterface调用一个JavaScript,将调用和响应外部页面信息,然后用布尔值回应闪光灯或打开弹出窗口,并拥有它调用并响应外部页面(如果没有,则显示错误消息等)。

完全取决于你在做什么zend的东西真的。

+0

似乎在顶部打开一个新窗口,只有在条件满足false时才必须关闭它。此外,它不解释为什么使用externalInterface和navigatetoURL操作与交互事件将使所有后续调用可用于延迟设置。 但它看起来像我将不得不在另一个用户确认过程中的某个地方工作。感谢您的链接 – Beans 2010-09-20 09:22:30

+0

从Flash 10开始,有几件事情受到了限制。与下载,上传功能相同。如果触发核心的事件是用户交互(鼠标单击或键盘事件),则可以使用此功能。我认为如果没有这个,我们会淹没成千上万的弹出窗口,自动从愚蠢的Flash添加开启。 – 2012-07-30 12:54:50

相关问题