charはだめよ、ということ。

 FireFox対応版、解決編。

  • ……FireFoxだと動かない(汗)。

 の原因のひとつについて。
 <IMG>タグのNAME属性に"char"を使ってたんだけど、予約語なのか、FireFoxだと使えませんでした。
index.html(誤)

<IMG NAME="char" SRC="Ki.jpg" BORDER="0"><BR>
<DIV ID="maintext"> </DIV><BR>
<input type="button" value="「喜」へ切り替え" 
    onClick="getData( 'dataKi.xml', document.char, 'maintext' ); return false;">
</form> <input type="button" value="「怒」へ切り替え" 
    onClick="getData( 'dataDo.xml', document.char, 'maintext' ); return false;">


 修正版は"character"にしてあります。


index.html

<IMG ID="character" SRC="Ki.jpg" BORDER="0"><BR>
<DIV ID="maintext"> </DIV><BR>
<input type="button" value="「喜」へ切り替え" 
    onClick="getData( 'dataKi.xml', 'character', 'maintext' ); return false;">
</form> <input type="button" value="「怒」へ切り替え" 
    onClick="getData( 'dataDo.xml', 'character', 'maintext' ); return false;">

 まぁ他にもFireFoxで動かなかった理由があるんだけどそれは後で。

枯れた新しいUI革命「Ajax」をASP.NETで活用する

 Ajaxの参考になりそうな記事と、その中のDOMリファレンスとJKL.ParseXMLへのリンク。

 明日書くけど、XMLのパーシングがIEFireFoxとで違ってて処理がが面倒なことになってるんで、JKL.ParseXMLでその辺が解決できるなら使ってみてもいいかも。

XMLの読み込み(FireFox対応版)。

[Ajax][JavaScript][XML]XMLの読み込み

 昨日のFireFoxに対応しました。


できちゃった

 昨日挙げたみっつの課題。

  • <IMG NAME="char">と<DIV ID="maintext">で渡し方が違うので統一したい。
  • XMLの各要素のアクセスにインデックスナンバーじゃなく文字列で指定したい。
  • ……FireFoxだと動かない(汗)。

 を解決してあります。
 それぞれの解決経過とかはあとで個別にしますです。

XMLの読み込み。

[Ajax][JavaScript]XMLの読み込み。

 XMLを読み込んで、画像とテキストまとめて変えるようにしてみました。


エロゲー


 まずはXMLファイルの用意。
dataKi.xml

<?xml version="1.0" encoding="UTF-8" ?>
<pages>
    <page>
        <image>Ki.jpg</image>
        <text>あははー</text>
    </page>
</pages>

 画像ファイルとテキストをこんなふうにXMLに持たせます。
 JavaScriptでこれをパーシングします……と思ったんですが、パーシングの必要ないんですね(汗)。

test.js

    // イメージを置き換えます。
    var imageUrl 
        = ajax.responseXML.documentElement.childNodes.item(0).childNodes.item(0).text;
    imageObjName.src = imageUrl;

    // テキスト置き換え先の取得。
    var textObj = document.getElementById( textObjId );
    // テキストを置き換えます。
    var text 
        = ajax.responseXML.documentElement.childNodes.item(0).childNodes.item(1).text;
    textObj.innerHTML = text;

 XMLHttpRequestがもうそのままXMLのDOMオブジェクトみたいに使えるんで、これをそのままアクセスできるんですねー。
 <image>タグにアクセスするためには、<pages><page><image>とアクセスします。
 「ajax.responseXML.documentElement」までが「<pages>」、次の「childNodes.item(0)」が「<page>」、次の「childNodes.item(0)」が「<image>」、最後の「text」がその中身。
 「(0)」っていうのは、XML内での上からの順番ね。だから「<text>」の方は「childNodes.item(1)」です。
 こういうふうにアクセスすればもうXML内の情報が取得できるとゆー。パーシングする必要がないのは楽だなぁ。


>追記


 コメントで、「childNodes.item(0)」は「childNodes[0]」でアクセスできることを教えて頂きました。

	// イメージを置き換えます。
	var imageUrl 
		= ajax.responseXML.documentElement.childNodes[0].childNodes[0].text;
	imageObjName.src = imageUrl;

	// テキスト置き換え先の取得。
	var textObj = document.getElementById( textObjId );
	// テキストを置き換えます。
	var text 
		= ajax.responseXML.documentElement.childNodes[0].childNodes[1].text;
	textObj.innerHTML = text;

 普通のオブジェクトと思ってたものが配列として扱えるって不思議だ。それとも、C++演算子オーバーロードみたいなもんと考えればいいのかな……。
 この形式で修正したのはこちらになります。


<追記ここまで。


 呼び出す方はこう。
index.html

<IMG NAME="char" SRC="Ki.jpg" BORDER="0"><BR>
<DIV ID="maintext"> </DIV><BR>
<input type="button" value="「喜」へ切り替え" 
    onClick="getData( 'dataKi.xml', document.char, 'maintext' ); return false;">
</form> <input type="button" value="「怒」へ切り替え" 
    onClick="getData( 'dataDo.xml', document.char, 'maintext' ); return false;">

 基本的にはこれまでの合わせ技で。


 XMLのパーシングが必要ないっていうのはちょっとビックリだ。なんかやることがだいぶ減ったな。
 とりあえず現在の課題。

  • <IMG NAME="char">と<DIV ID="maintext">で渡し方が違うので統一したい。
  • XMLの各要素のアクセスにインデックスナンバーじゃなく文字列で指定したい。
  • ……FireFoxだと動かない(汗)。

 次はその辺調べてみましょう。

画像の切り替え

[キャラ]謎キャラ

 JavaScriptで画像を切り替える、というのを試してみました。*1


サンプル:画像の切り替え

 2枚の画像を切り替えるというシンプルなのです。


index.html

<input type="button" value="「怒」へ切り替え" 
    onClick="changeImage( document.kido, 'Do.jpg' ); return false;">
</form>
<input type="button" value="「喜」へ切り替え" 
    onClick="changeImage( document.kido, 'Ki.jpg' ); return false;">
</form><BR>
 <BR>
<IMG NAME="kido" SRC="Ki.jpg" BORDER="0"><BR>
  • IMGタグのNAMEパラメーターで、そのタグの名前(ここでは"kido")を付ける。
  • そうするとdocument.kidoでそのタグにアクセスできる。

 これをchangeImage()メソッドに渡します。

test.js

/**
    画像を切り替えます。
    @param objName 切り替え先。<img name="xxx"> なら document.xxx を渡せばOK。
    @param imageUrl 画像のURL。
*/
function changeImage( objName, imageUrl )
{
    // objName で渡されたオブジェクトの src パラメーターを
    // imageUrl で置き換えます(結果、画像が変わります)。
    objName.src = imageUrl;
}

 引数objNameで渡された「IMGタグのオブジェクト」のsrcパラメーターを、imageUrlで渡された「画像のURL」で置き換えます。
 すると画像が切り替わります。


 ……フィールドに値を入れたら実際に置き換わる、ゆーんは慣れないなぁ。
 C#のアクセサみたいなもんか? あの、実際にはメソッドが呼ばれるゆー。
 そう思うことにしよう。


 これで画像の切り替えができたから、次はXMLのパーシングかな。

*1:Ajax関係なし。

とりあえず始めてみよう。

 なにはともあれ、Ajaxを始めてみましょう。
 とりあえず以下のサイトを参考に作ってみます。

 Ajaxは"Asynchronous JavaScript + XML"(非同期で JavaSrcipt と XML*1)の略で、 JavaScript から利用できる XMLHttpRequest クラス(って言っちゃいけないのか?)を使うとデータを取ってきて画面に出力できたりするシステムなんですなー。
 一昔前だと、こういうのはインラインフレーム使わなきゃ無理って話だったのに、いつのまにこんなもんが……。
 まぁこの機能を使えば、任意のファイルを動的に取ってきて、一部のテキストやイメージだけを差し替えることができるみたいで、これでエロゲーを作ってしまおうという。
 ちなみに「エロゲー」というのはこんな感じの、ウィンドウ型テキストノベルを想定してます。


エロゲー

 別に「Ajaxでギャルゲーを作るブログ」や「Ajaxでテキストノベルを作るブログ」でも良かったんだけど、「エロゲー」が一番分かりやすいかなと思って。っつーてもエロは少なめだけど。はてなは原則どエロ禁止だし。


 さて、とりあえずサンプルを作ってみました。

 環境は以下のような感じ。

 今回のテストではサーバーサイドの機能は使いませんでした。全部静的なファイルです。その方が楽だと思って。
 エロゲー作る時も多分そうすると思う。ちょっと管理大変かもしれないけど……。


 では、このサンプルの解説。


・index.html

<html>
<script language="JavaScript" src="test.js"></script>
<head><title>Ajaxでエロゲーを作るブログ - とりあえず始めてみましょう</title></head>
<body>
<form>
<input type="button" value="クリックしてね" 
	onClick="getData('text.html', 'maintext'); return false;">
</form>
<div id="maintext">ここが置き換わります。</div>
</body>
</html>

 JavaScriptのファイルは<script>タグで指定しています。ボタンがクリックされたら、その中にあるgetData()メソッドを呼び出します。その際、置き換えるテキストファイル「text.html」と、置き換え先のオブジェクトID「maintext」を渡します。


test.js

/**
    XMLHttpRequestのインスタンスを作って返します。
*/
function createXMLHttpRequest()
{
    if( window.XMLHttpRequest )
    {
        // IE以外の場合
        return new XMLHttpRequest();
        // alert( "window.XMLHttpRequest" );
    }
    else if( window.ActiveXObject )
    {
        // IE用
        try
        {
            return new ActiveXObject( "Msxml2.XMLHTTP" );
            // alert( "Msxml2.XMLHTTP" );
        }
        catch(e)
        {
            return new ActiveXObject( "Microsoft.XMLHTTP" );
            // alert( "Microsoft.XMLHTTP" );
        }
    }

    return null;
}

/**
    指定したURLからテキストを取ってきて置き換えます。
    @param serverURL HTMLを取ってくるURL
    @param objID 置き換え先のID。
*/
function getData( serverURL, objID )
{
    // XMLHttpRequestを取得します。
    var ajax = createXMLHttpRequest();

    // URL を指定して、そこから情報を取ってきます。
    ajax.open( "GET", serverURL );

    // 状態が変化したら呼ばれるイベントハンドラをセットします。
    ajax.onreadystatechange 
        = function()
        {
            if    (
                ( ajax.readyState == 4 ) && 
                ( ajax.status == 200 )
                )
            {
                // ちゃんと読み込めてたら置き換え。
                
                // 置き換え先の取得。
                var obj = document.getElementById( objID );
                // テキストを置き換えます。
                obj.innerHTML = ajax.responseText;
            }
        }

    ajax.send( '' );
}

 createXMLHttpRequest()でXMLHttpRequestを取得。
 XMLHttpRequest#open()で、指定したURLから情報を取得。
 XMLHttpRequest#onreadystatechangeにイベントハンドラをセット。JavaScriptって、無名クラスっぽい感じにメソッドをその場で作れるのか、なんか不思議だ……。
 成功したら、取得した情報がXMLHttpRequest#responseTextに入っているから、これをgetData()の第2引数に渡されたオブジェクトにセット、という感じかな。


 んで、その置き換えるデータ。

text.html

クリックされました!

 これだけ。テキストファイルでも良かったんだけど、なんとなく。
 ただ、日本語を使うために、これだけはUTF-8で保存する必要があります。秀丸エディタを使っているので、そのままUTF-8形式で保存しました。それが一番楽かと。


 以上3ファイルを、FTP等でホームページに置いてください。index.htmlにアクセスして、「クリックしてね」ボタンを押すと、下の「ここが置き換わります」が置き換わると思います。
 ローカルに置いたファイルに対してC:\index.htmlみたいな感じでアクセスしても動きませんでした。セキュリティ的な問題かな? うちは自宅サーバーで、ファイルの置き場所は共有化してあるんで置いてあるのをそのまま修正しちゃってるけど……。
 それと、キャッシュの問題か、text.htmlの中身を修正しても反映されませんでした。これはなんでだろう。ちょっと修正が面倒かも……。


 ……これだけ見ると、単に非同期でデータを取ってくる、ってところはそんな難しくなさそうな気が。
 当面の課題としては、以下のようなところかな。

  • イメージの置き換えはどうするのか。
  • XMLで「置き換えるテキスト」「置き換えるイメージ」「次のテキストが入っているファイル」とかを格納してパーシングする必要あり。

 なんか、思ったよりもAjax単体では簡単そうな気が。
 むしろ、XMLのパーシングや、CSSの知識が必要になってきそう。その辺をこつこつ調べていきましょう。

*1:なんじゃそりゃ。