AS3 ExternalInterface / navigateToUrl блокирует всплывающие окна при вызове из setTimeout - PullRequest
0 голосов
/ 20 сентября 2010

Эта проблема заставляет меня рвать на себе волосы.

Симптомы : всплывающие окна периодически блокируются / пропускаются через внешний интерфейс и комбинации navigateToURL.

Проблема : Flash (или браузер ... не уверен) не позволяет запускать всплывающие окна вне временного диапазона и / или продолжительности события.

Среда : Iиметь приложение, которое должно отправлять данные через ZendAMF, выполнять некоторую обработку и отправлять обратно на флэш-плеер.Если в ответе соблюдены определенные условия, то откройте всплывающее окно.Тот же код, который блокируется при ответе, работает непосредственно из триггера события мыши.

Итак, я настроил базовую ситуацию: 6 кнопок, вызывающих 3 метода.3 кнопки будут вызывать метод напрямую (все откроют окно идеально), остальные три получат значение числового степпера и будут использовать setTimeout (openWinMethod, NumericStepper.value) для имитации отложенного вызова из ответа zendAMF.

ОБНОВЛЕНИЕ : если я сначала выберу кнопку «navigateToURL, no delay», закрою это окно, а затем попробую любой другой вызов с задержкой - они работают.Это похоже на то, что браузер признает, что вы щелкнули, чтобы открыть окно в какой-то момент, и, следовательно, вам разрешено звонить с задержкой, а затем.(только Firefox)

Все три, использующие задержку, будут заблокированы (Firefox и Chrome), тогда как все три будут открыты напрямую.Safari - как хорошо задокументировано, будет работать только с двумя методами, использующими navigateToURL

. : функция js в оболочке html будет называться внешним интерфейсом для открытия окна.Без задержки это сработало.С задержкой будет вызвана функция js (что подтверждается некоторыми операторами оповещения), но новое окно никогда не появлялось.

Есть два варианта, с которыми я столкнулся: 1 - изменить процесс так, чтобы он требовал пользователянажмите, чтобы продолжить, как только я получу ответ от zenAMF, или 2 - узнайте, почему это происходит, и исправьте его (предпочтительно)

, демонстрацию можно найти здесь: 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>

1 Ответ

0 голосов
/ 20 сентября 2010

прочитайте это: Требования к взаимодействию с пользователем

вы заметите, что во всплывающих окнах как externalInterface, так и navigatetoURL указаны как реагирующие только на взаимодействие с пользователем.в основном то, что вы делаете, будет заблокировано, если вы запускаете скрипт, который занимает слишком много времени.

если вы хотите сделать что-то подобное, тогда либо используйте вызов ExternalInterface к javascript, который будет вызывать и реагировать на информацию о внешней странице, затем отвечайте логическим значением обратно на флэш-память или все равно откройте всплывающее окнопусть он позвонит и ответит на внешнюю страницу (отобразит сообщение об ошибке и т. д., если нет).

действительно зависит от того, что вы делаете с вещами Zend.

...