flashからjavascriptの関数を実行する

前回の続きで、今度はactionscript内からhtml内に含まれているjavascript関数を実行します。proxyオブジェクトの用意は前回で出来ているので、今回の作業はactionscriptから呼ぶjavascript関数の用意とその関数をproxy経由で呼び出すコードをactionscript内に用意するだけです。

flash2js.as

class Application {
  static var app:Application;
  var proxy:JavaScriptProxy;

  var log:Function;
  function initDebugger():Void {
    _root.createTextField( "tf", 1, 0, 0, 100, 20 );
    _root.tf.border = true;
    _root.tf.text = "";
    this.log = function( msg:String ) {
      _root.tf.text = msg;
    }
  }
  
  function Application() {
    var self:Object = this;
    proxy = new JavaScriptProxy( _root.lcId, this );
    initDebugger();
    log( _root.lcId );

    var counter:Number = 0;
    setInterval( function() {
      self.proxy.update_html( "update html from flash, count=" + counter );
//      self.proxy.call( "update_html", "update html from flash, count=" + counter );
      counter = ( counter < 60 )  ?  counter + 1 : 0;
    }, 1000 );
  }

  public static function main () {
    app = new Application();
  }
}

Applicationコンストラクタ内のsetInterval付近が今回の追加コード。1秒おきにjavascript関数を実行する。proxy.call関数にjavascript関数名とそのパラメタを渡す形式と、proxyのメソッドとして直接呼ぶ形式のどちらかで実行可能。

index.html

<html>
<head>
  <title>flash2js sample</title>
  <script type="text/javascript" src="./proxy/JavaScriptFlashGateway.js"></script>
</head>
<body>
  <script type="text/javascript">
  <!--
    var uid = new Date().getTime();
    var flashProxy = new FlashProxy( uid, './proxy/JavaScriptFlashGateway.swf' );
  //-->
  </script>
  <h1>flash2js</h1>
  <script type="text/javascript">
  <!--
    var tag = new FlashTag( 'flash2js.swf', 200, 200 );
    tag.setFlashvars( 'lcId=' + uid );
    tag.write( document );
  //-->
  </script>
  <p><a href="javascript:flashProxy.call('log', 'logging from js!!!');">process flash function()</a></p>
  <p><a href="javascript:(function(){
    alert( 'uid = ' + uid );
  })();">check uid value</a></p>
  <div id="editable">hoge</div>
  <a href="javascript:update_html('update from javascript in html');">update from javascript in html</a>
</body>
<script type="text/javascript">
<!--
function update_html( string ) {
  document.getElementById( "editable" ).firstChild.nodeValue = string;
}
//-->
</script>
</html>

actionscript側から呼んでもらうためのupdate_html()関数を追加する。flash2js.asをコンパイルし、index.htmlを開くと1秒おきにid=editableのdivが更新されることを確認した。

ただし、ローカルマシン内に配置したflash,htmlで試験を行っていると、flash側から通信が発生している状態となるのがセキュリティ的に引っかかるらしく、Macromedia - Flash Player : 設定マネージャ パネルでアクセス設定の変更が必要でした。「常に確認」かつ「これらのファイルとフォルダを常に信頼する」に入れるとflash->jsの呼び出しは可能だけどjs->flashの呼び出しが出来なくなってしまいました。「常に許可」だとどちら側からも呼び出し可能となりました。
外に公開しているサーバに配置して確認したところ、セキュリティ設定の変更は不要でした。この辺りの話は自分が知らなかっただけで割と一般的なことかもしれません。