「(5) .fbd ファイルを読み込む」で配列 fbd_xml の各要素をXMLオブジェクトにして .fbd ファイルのXMLデータを読み込ませました。

ではいよいよ読み込んだデータをテキストエリアに表示しましょう。

とその前に先ほど述べたように配列 fbd_xml のXMLオブジェクトに load メソッドを用いて .fbd ファイルを読み込ませましたが、その内容をテキストエリアに表示するためには読み込みが完了していなければなりません。

通常なら onLoad イベントハンドラを用いるのですが、今回は複数のファイルを同時に読み込むという動作を行っているので、その全ての読み込みを判断するのに単独のオブジェクトのイベントを監視する onLoad イベントハンドラを用いるのは適切ではありません。

従って今回は fbd_xml オブジェクトの読み込みを監視する空のムービークリップを配置して onEnterFrame イベントハンドラメソッドの中で処理を行います。

まず daylist_xml.onLoad の続きに読み込みフラグを設定するスクリプトを追加します。

 // 読み込みフラグを立てる
 _global.fl_fbdread = true;

次にレイヤー「変数定義」と「main」の間にレイヤー「MC」を新規作成します。そして「挿入」→「新規シンボル」で中身が空のムービークリップを作成します。名前は自由に設定して結構ですが、今回はライブラリから管理しやすいよう「mc_firstread」と設定します。

この新たに作成したムービークリップ「mc_firstread」をレイヤー「MC」に配置してインスタンス名も同じ「mc_firstread」にします。インスタンス名はムービークリップを選択するとプロパティウィンドウから設定できます。

ムービークリップのイベントハンドラ EnterFrame はこれまではムービークリップそのものにスクリプトを記述しましたが、FlashMXからはイベントハンドラメソッドを用いてタイムライン上に記述することが可能になりました。ここではその方法を用います。
先ほどのレイヤー「MC」のタイムラインに mc_firstread.onEnterFrame の関数を記述します。

mc_firstread.onEnterFrame = function() {
}

mc_firstread インスタンスは1フレームしかないムービークリップなので、この関数の処理は1秒間にフレームレートの回数だけ処理が行われるので、この中に読み込みチェックの処理を記述してきます。

 if (_global.fl_fbdread) {
  var dfload = 0;  // DayFileLoad 各日ファイルを読み込んだ数を入れる変数
  for (i = 0; i < _root.fbd_xml.length; i++) {
   if (_root.fbd_xml[i].firstChild.nodeName == "blogdata") {
    dfload++;
   }
  }
  if (dfload == _root.fbd_xml.length) {
   _global.fl_fbdread = false;
   _global.view_newest = true;  // 最も最近にエントリされたデータを表示するフラグを立てる
  }
 }

まず最初に読み込みフラグ _global.fbdread がtrueかどうかをチェックし、trueだった場合にのみ次の処理へ移るようにします。

次に .fbd ファイルを読み込んだ数をチェックするためのローカル変数 dfload を定義します。そしてXMLデータを入れるために定義した fbd_xml オブジェクトの数だけ読み込みのチェックを行い、読み込みが確認されたら変数 dfload の数を1追加します。チェックには XMLオブジェクトの一番最初のノードに <blogdata> タグがあるかどうかで判断するようにしています。

一通りのチェックが終わると変数 dfload の値が fbd_xml オブジェクトの数と同じかをチェックします。ここでもし同じであれば全ての読み込みが完了したと判断して次の処理に移り、同じでなければ処理を終了して次のフレームに進みます。変数 dfload の値は次のチェック処理の時に初期化されるのでそのままにしておいて結構です。

全ての読み込みが完了したと判断したら、読み込みフラグ _global.fl_logread はfalseにしてチェック処理を行わないようにします。そしてデータ表示フラグ _global.view_newest をtrueとして定義します。

blogデータ表示のためにレイヤー「main」にテキストエリアを3つ、それぞれのインスタンス名を「date」「title」「log」として配置し、3つとも「テキストをHTMLとしてレンダリング」「テキストの周囲にボーダーを表示」にチェックを入れ、「date」「title」は単一行、「log」は複数行にします。

 // 最も最近にエントリされたデータを表示する
 if (_global.view_newest) {
  date.htmltext = _root.fbd_xml[0].firstChild.childNodes[0].attributes["year"] +"年" +
          _root.fbd_xml[0].firstChild.childNodes[0].attributes["month"] +"月" +
          _root.fbd_xml[0].firstChild.childNodes[0].attributes["day"] +"日";

  title.htmltext = "<b>" + _root.fbd_xml[0].firstChild.childNodes[1].firstChild.nodeValue + "</b>";
  log.htmltext = _root.fbd_xml[0].firstChild.childNodes[2];

  _global.view_newest = false;
 }

あとは fbd_xml[0] オブジェクトの内容をそれぞれのテキストエリアに表示させて、表示フラグ _global.view_newest をfalseにして処理を終了します。

ちなみにXMLのノード内にHTMLタグが含まれていると実際は当然ながらHTMLタグ部分もXMLとしてオブジェクト内に格納されています(デバッグでXMLオブジェクトの中身を見るとわかると思います)。しかしテキストエリアに表示するときはHTML部分はそのまま残しておきたいのでデータを取り出すときはそのHTMLが存在するノードの親ノードの内容を表示するようにします。ここでは _root.fbd_xml[0].firstChild.childNodes[2] の内容(<content> タグの中身)を全て表示することで実現しています。


さて、これで初回読み込み時の基本的な動作が実現できました。今後は全体的な機能とインターフェイスを考えて行こうと思いますが、これがなかなか大変な作業なので次回の更新はかなり先になるかもしれません。


今回の構成ファイルをダウンロードできるようにしました。
>> ダウンロード
前回の「(4) daylist.xml を読み込む」で最新のblogデータが含まれている月の daylist.xml を読み込んでその月の .fbd ファイルの名前リストを取得しました。

今回はblogデータ本体である .fbd ファイルを読み込みます。

まず最初に読み込む .fbd ファイルの数を設定します。これはレイヤー「変数定義」に以下のスクリプトを追加します。

// 最初に読み込む .fbd データの数
_global.firstload = 5;

変数 _global.firstload の数は自由に設定してください。今回は5つ分のデータを読み込むこととします。

ではいよいよメインのスクリプトです。.fbd ファイルの名前は daylist_xml.onLoad の関数内で取得したので、その続きにファイルを読み込むスクリプトを追加します。

 // .fbd ファイルを読み込む
 fbd_xml = new Array();
 for (i = 0; i < _global.firstload; i++) {
  if (readlog[i].toString) {
   fbd_xml[i] = new XML();
   fbd_xml[i].ignoreWhite = true;

   fbd_xml[i].load(firstLoad["year"] + "/" + firstLoad["mon"] + "/" + readlog[i]);
  }
 }

複数の .fbd ファイルを読み込むため、.fbd ファイルのXMLを入れる fbd_xml オブジェクトは配列にしておきます。そして存在しないファイルを読み込もうとするのを防ぐため if (readlog[i].toString) で動作の振り分けをしています。

これで配列 fbd_xml の各要素に .fbd ファイルのXMLデータが読み込まれます。

ところで現在のサンプルデータはblogデータを3つしか入れておらず、このままでは初回読み込み時に5つのblogデータを表示することができません。本来ならばその月のblogデータが5つに満たない場合は前の月に遡ってデータを取得すべきなのですが、この動作を実現するのはなかなか難しいのでしばらくはこの仕様のまま作成を続けようと思います。blogデータを表示する動作まで一通り作成したときに改めて修正を加えるつもりです。

今回の構成ファイルをダウンロードできるようにしました。
>> ダウンロード
Flashの作業ファイル(.fla)は作業をしているうちにどんどん容量が増えて行きます。とくにビットマップ画像や音声ファイルなどを使用する場合は元のデータとなるJPEGファイルやPNGファイルを取り込んでいるため簡単に数MBになることもあります。

実はこの .fla ファイルは取り込んだ画像データなどをライブラリから削除してもそのまま上書き保存をすると容量はそのままの状態になります。ライブラリから消された時点でデータはなくなっているはずなのになぜこういうことになるのかは不明なのですが、そういうところがマクロメディアのマクロメディアたるところかもしれません。マクロメディア製品はアドビ製品と比べるとどうも精錬された感じがしないのは私だけでしょうか。

さて、この容量が減らない .fla ファイルですが、別名で保存するとしっかりと容量が減ってくれます。「ライブラリのデータを削除したら別名保存」をお忘れなく。
使い出すととても便利なダイナミックテキストですが、弱点の一つにマスクの対象にすると文字が全て消えてしまうというものがあります。例えばダイナミックテキストが配置されているレイヤーがマスクの対象になっていた場合、それが例え表示される領域であってもダイナミックテキストの部分にはなにも表示されません。

しかしこれはActionScriptでマスクを設定することで回避することができます。ActionScriptでのマスクの指定方法は setMask メソッドを用います。

targetMovieClip.setMask(maskMovieClip);

targetMovieClip はマスクの対象となるムービークリップで、このムービークリップにダイナミックテキストを配置します。そして setMask の引数である maskMovieClip はマスク領域にするムービークリップのインスタンス名です。

ただし、 maskMovieClip の形状は矩形でなければなりません。これが円形などの矩形以外の形状だった場合、境界枠(オブジェクトを選択したときに現れる水色の四角い枠)がマスク領域になります。
ymlist.xml を読み込んだことによってblogデータの存在する年と月を取得され、次に読み込むべき年フォルダと月フォルダも導き出されます。月フォルダには必ずその月の何日にblogデータがあるのかを定義した daylist.xml があるので、そのファイルを読み込んで1日分のblogデータのファイル名リストを取得します。

まず daylist.xml のXMLデータを入れるXMLオブジェクトを定義します。

(「変数定義」レイヤー)
// 日付を定義したXML
daylist_xml = new XML();
daylist_xml.ignoreWhite = true;

次に読み込む年フォルダと月フォルダは前回の ymlist_xml.onLoad の関数で定義した配列 firstLoad を用います。前回記述した ymlist_xml.onLoad の関数の中の続きに以下のスクリプトを追加します。

// 最初に読み込む daylist.xml の内容を取得
daylist_xml.load(firstLoad["year"] + "/" + firstLoad["mon"] + "/daylist.xml");

これによって daylist_xml オブジェクトに指定された年月の daylist.xml のXMLデータを読み込む動作が発生します。

daylist_xml オブジェクトにXMLデータが読み込まれたら、その月のblogデータのファイル名を配列 readlog に入れます。

(「onLoad」レイヤー)
daylist_xml.onLoad = function() {
 // 読み込む .fbd ファイル名を取得
 readlog = new Array();

 // <daylist>タグに囲まれた一番最初のタグ(<dayfile>)を変数 tmp_daylist_xml に設定
 var tmp_daylist_xml = daylist_xml.firstChild.firstChild;

 // <dayfile>タグがなくなるまで処理を繰り返す
 while (tmp_daylist_xml != null) {
  readlog.push(tmp_daylist_xml.firstChild.nodeValue);

  // 次の<dayfile>タグへ進む
  tmp_daylist_xml = tmp_daylist_xml.nextSibling;
 }
}

これで配列 readlog にその月のblogデータのファイル名が入れられました。

実はその月で一番最新のblogデータのファイル名を取得するだけなら配列に入れる必要はなく、
daylist_xml.onLoad = function() {
 readlog = daylist_xml.firstChild.firstChild.firstChild.nodeValue;
}

と記述することで変数 readlog にファイル名が入れられます。しかし今回は初回読み込み時に複数の日付のblogデータを表示することも考えているので配列に入れることにしています。


今回の構成ファイルをダウンロードできるようにしました。前回の daylist.xml は<dayfile>タグの並びが昇順になっていたのですが、今回は ymlist.xml と同様に降順に修正しています。
>> ダウンロード