10

ページで Javascript を呼び出してデータを取得する必要がある Flash ゲームに取り組んでいます。Flash から Javascript を呼び出すことができます。Javascript から Flash 関数を呼び出すと (多くの場合)、そうではありません。

Gaia フレームワークを使用しています。

何が起こるのですか:

  1. swf は SWFObject で読み込まれます
  2. Flash ファイルにボタンがあります。クリックExternalInterface.call()すると、Javascript 関数を呼び出すために使用されます。これは機能します。
  3. Javascript 関数は、 で公開された Flash 関数を呼び出しますExternalInterface.addCallback()
  4. 時々、Javascript は次のエラーを生成します: TypeError: myFlash.testCallback is not a function.
  5. エラーが発生すると、 に登録されているすべての関数に影響しaddCallback()ます。Gaia とそれに含まれるライブラリの一部は を使用しaddCallback()、Javascript からこれらの関数を呼び出すと、TypeError も生成されます。
  6. Flash でボタンを押す前に長時間待っても、エラーは解決しません。
  7. Flash を定期的に再試行addCallback()してもエラーが解決しない
  8. エラーが発生した場合ExternalInterface.available = trueExternalInterface.objectIDFlash 埋め込みオブジェクトの正しい名前が含まれています。
  9. エラーが発生した場合、document.getElementById('myflashcontent')Flash 埋め込みオブジェクトを正しく返します。

追加するために編集:

  • この問題は Firefox 3.6 で発生しますが、Chrome や IE8 では発生しません。古いブラウザは試していません。
  • Flash Player のデバッグ バージョンを実行しています。
  • 私の呼び出しはブロックExternalInterface.addCallback()にラップされています。try...catchJS エラーが発生すると、catchブロックトリガーされません。サイレント失敗です。
  • エラーは、swf がページと同じサーバーからロードされた webhost でテストするときに発生します。
  • 設定しallowScriptAccess = alwaysました。
  • 設定flash.system.Security.allowDomain("mydomain")してもエラーは解決しません。

私のページクラスから:

public class MyPage extends AbstractPage
{
    // declarations of stage instances and class variables

    // other functions

    override public function transitionIn():void 
    {
        send_button.addEventListener(MouseEvent.MOUSE_UP, callJS);
        exposeCallbacks();

        super.transitionIn();
    }

    private function exposeCallbacks():void
    {
        trace("exposeCallbacks()");
        if (ExternalInterface.available) {
            trace("ExternalInterface.objectID: " + ExternalInterface.objectID);
            try {
                ExternalInterface.addCallback("testCallback", simpleTestCallback);
                trace("called ExternalInterface.addCallback");
            }
            catch (error:SecurityError) {
                trace("A SecurityError occurred: " + error.message + "\n");
            }
            catch (error:Error) {
                trace("An Error occurred: " + error.message + "\n");
            }
        }
        else {
            trace("exposeCallbacks() - ExternalInterface not available");
        }
    }

    private function simpleTestCallback(str:String):void
    {
        trace("simpleTestCallback(str=\"" + str + "\")");
    }

    private function callJS(e:Event):void
    {
        if (ExternalInterface.available) {
            ExternalInterface.call("sendTest", "name", "url");
        }
        else {
            trace("callJS() - ExternalInterface not available");
        }
    }

}

私のJavascript:

function sendTest(text, url) {
    var myFlash = document.getElementById("myflashcontent");

    var callbackStatus = "";
    callbackStatus += '\nmyFlash[testCallback]: ' + myFlash['testCallback'];
    //console.log(callbackStatus);

    var errors = false;
    try {
        myFlash.testCallback("test string");
    }
    catch (err) {
        alert("Error: " + err.toString());
        error = true;
    }

    if (!error) {
        alert("Success");
    }
}

var params = {
    quality: "high",
    scale: "noscale",
    wmode: "transparent",
    allowscriptaccess: "always",
    bgcolor: "#000000"
};
var flashVars = {
    siteXML: "xml/site.xml"
};
var attributes = {
    id: "myflashcontent",
    name: "myflashcontent"
};

// load the flash movie.
swfobject.embedSWF("http://myurl.com/main.swf?v2", "myflashcontent",
"728", "676", "10.0.0", serverRoot + "expressInstall.swf",
flashVars, params, attributes, function(returnObj) {
    console.log('Returned ' + returnObj.success);
    if (returnObj.success) { returnObj.ref.focus(); }
});
4

8 に答える 8

2

ExternalInterface を介して行われた JS への呼び出しはtry { }ブロック内にラップされるため、後続の JS エラーが抑制されます。

同じ問題を回避するには、JavaScript で関数を閉じ、タイムアウト後に実際のコードを実行します。

例:

function myFnCalledByEI (arg1, arg2) {

    setTimeout(myActualFunction () {
       // You can use arg1 and arg2 here as well!
       // Errors raised within this function will not be
       // suppressed.
    }, 0);

};
于 2010-06-22T15:30:46.193 に答える
1

これは、発生している問題に似ている可能性があります。

http://www.google.com/support/forum/p/translator-toolkit-api/thread?tid=58cda1b34ae1e944&hl=en

于 2011-06-14T22:24:21.870 に答える
1

すべての条件を絞り込んだ後のシナリオは次のとおりです。

  • FireFox/Windows のみ
  • wmode=transparent の場合のみ
  • js alert() 関数を使用する場合のみ

この特定のシナリオでは、ExternalInterface.call() はすぐには起動しません。Timer クラスで小さな遅延を作成した後にのみ機能しました。

wmode=window を作成するか、alert() を削除すると、すべてが機能しました。console.log() を使用して、firebug にデバッグ テキストを表示してみてください。

他の落とし穴?js 関数が配列またはオブジェクトと文字列のどちらを返すか。驚くべきことに、ネイティブの js 配列を返すと、Flash では配列によって解釈されました。次のような戻りデータに関する情報を出力してみてください。

var myRetVal = flash.external.ExternalInterface.call("my_js_func");
debug_txt.text = flash.utils.describeType(myRetVal).toString();
于 2011-01-27T17:27:49.370 に答える
0

JavaScriptでこれを試しましたか?

if (myFlash)    
{
  if (!myFlash.testCallback)
  {
    if (__flash__addCallback)
    { 
       __flash__addCallback( myFlash, "testCallback" );
    }
    else
    {
      console.log("Error: Flash External Interface injected JavaScript function not found. The external interface function won't work.");
    }
  }
}

myFlash.testCallback("test string");  

私はこれを多くの場合使用していました。

ここでも、エラーを最小限に抑えるために、特定の場所で__flash_addCallback関数と_flash_removeCallback関数を再定義する必要がありました。

現在、__ flash_addCallbackに対して何をしたかは覚えていませんが、後者に対して行ったことは次のとおりです。

if (__flash__removeCallback) 
{
   __flash__removeCallback = function (instance, name) {if(instance && instance[name]) instance[name] = null;
}
于 2011-06-04T14:15:05.027 に答える
0

私はあなたのコードを試してみましたが、すべての前にアラートを配置しても問題なく機能したので、それはあなたが待たなければならない何らかの時間に関連していると思います.

于 2010-06-29T21:06:14.267 に答える
0

呼び出し中に Flash で何か問題が発生した場合、そのタイプのエラー メッセージが表示されます。キャッチされない例外のようなもの。

プレーヤーのデバッグ バージョンを実行していますか? これにより、何が起こっているかについてより多くの情報が得られる場合があります。

また、これはブラウザー間で一貫していますか? 以前のバージョンの IE では、複数の Flash <-> JS 呼び出しを連続して受け入れるのに問題があるのを見てきました。

J

于 2010-04-14T06:30:24.100 に答える
0

ページに同じ Flash ファイルが複数回あったため、このエラーが発生していました。それぞれが異なる ID/名前を持っていたとしても、それらはすべて同じコールバックを使用していました。

于 2012-05-14T02:08:30.303 に答える
0

同じ問題に遭遇しましたが、Firefox でのみです。

THM からのアドバイスに従って、解決策を見つけることができました。

私たちの場合、挿入される swf は、jQuery.slideDown() でビューにアニメーション化される div 内にありました。これにより、起動中に再起動することがあるようです。場合によっては、これによりコールバック関数が利用できなくなりました。

slideDown 効果が終了した後にのみ、swfobject.embedSWF を呼び出すことで修正されました。

于 2011-09-01T12:58:34.720 に答える