2007年6月5日

『前の投稿』で遷移すると写真が表示されない(解決!)

これまで写真の投稿は次のようにしていた。

<div id="photo527593023"></div>
<script type='text/javascript'>
 writePhotoMap("527593023");
</script>

青の数字の部分がflickrのphoto ID。この投稿のHTMLが読み込まれると、<script>内の関数writePhotoMap()が実行されて、 <div id="photoXXXXXXXXX">に写真とかが色々とjavascriptで書き込まれていくというのが、当初のもくろみ。

通常は、これで問題なく写真とかが表示される。ところが、トップ画面の一番下にある『前の投稿』で、過去記事を見ようとすると、見れない!試しに上記のwritePhotoMap()の前にalert("");とか入れても、何もポップアップされない。どうやら<script>内が実行されていないらしい。ならば、と<body>にonload="alert('');"を付け加えてみるけど、これも実行されない。

アドレスバーとか『前の投稿』のリンクを見ると、java servletにGET送信して、リダイレクト?かなんかで過去の記事を表示しているみたい。う~ん、このリダイレクトか何かは仕事でも悩まされたことがあった。そのときに探せた情報は概念的なものばかりで。tomcatとbrowserとの間での細かいやりとりの仕組みが分からなかった。ここで嫌な予感が…。

とりあえず、WEBで情報収集しようとしてみたけど、なかなか難しい。検索語はonload javascript? なんか違う。次にbloggerのヘルプであるような気がした。Google Mapsをblogで表示したい時は同じ問題に行き当たるはず。ここで『前の投稿』をprevious postsと訳してしまった。不覚。正解はolder posts。例えば、AdWords API Blogの一番下で確認できる。

まぁ、辿り着いたのがDummies Gide to Google Blogger BetaのAdd a Google Map to your blogというページ。ここのサンプルソースに<onunload="GUnload()">>というのが<body>タグに付けてある。これが対策かと思ったけども、関数GUnload()はどこにも定義されていない。

とりあえず、unload javascriptで検索。そこで引っかかったのがMSDNのonload Eventのページ。APPLET, BODY, EMBED, FRAME, FRAMESET, IFRAME, IMG, LINK, SCRIPT, windowのオブジェクトでこのイベントは取得できるとのこと。MSのJScriptということで一抹の不安はあったけど、とりあえず、適当に<IMG>を入れて使ってみた。そしたら成功。どきどきしながらFirefoxで実行。これも上手く動いた。やったー。

あとは、<IMG>を不自然なく入れればOK。そこでカメラアイコンをチョイス。結果は以下のコード。

<IMG src="http://genisgen.googlepages.com/maps_camera.png" class="camera" onload="writePhotoMap('527593023');"><div id="photo527593023"></div>

写真の投稿の場合は、まずカメラアイコンを表示し、そのアイコンを呼び出す時に写真とかの記事本体の情報をその後ろにある<div>に書き込むと、理解できる。

なんか対処療法的で問題のような気もしたけど、このソースはある意味分かりやすいと思った。ソースに明示的に「いつ」(=カメラアイコンが呼び出された時)写真とかの記事本体を書き込むのかが書かれている。いままでのソースだと、browserがソースをparseしていって<script>のところで、書き込み命令を実行していたと理解しなければいけなかったので、browserのparseという非明示的なところを意識しなければならなかった。

ということで、このソースで良しとすることにした。アイコンのお陰で、写真に関する投稿だと分かりやすくなったし。まぁ、普通にblogをみる人は、まさかこのアイコンがあって初めて記事本体が表示されるとは思わないだろうけど…。(了)

2007年6月3日

アジサイのこれから

on the way to my friend' house 友達の家への道中

Flickr API

<input type="button" value="call" onClick="callFlickr();">
<script src="prototype.js" type="text/javascript"></script>
<script type="text/javascript">
<!--
 function callFlickr(){
    var param={};
    // APIリクエストパラメタの設定
    param.method   = 'flickr.photos.getSizes';
    param.api_key  = '46aae73ef606fb170b318268699a991a';
    param.photo_id = '496065935';
    param.format   = 'json';
    param.jsoncallback = 'jsonFlickrApi';

    // APIリクエストURLの生成(GETメソッド)
    var url = 'http://www.flickr.com/services/rest/?'+
               obj2query( param );

    // script 要素の発行
    var script  = document.createElement( 'script' );
    script.type = 'text/javascript';
    script.src  = url;
    document.body.appendChild( script );
    document.write("FlickrAPI done.");
 }

 // オブジェクトからクエリー文字列を生成する関数
 function obj2query ( obj ) {
    var list = [];
    for( var key in obj ) {
        var k = encodeURIComponent(key);
        var v = encodeURIComponent(obj[key]);
        list[list.length] = k+'='+v;
    }
    var query = list.join( '&' );
    return query;
 }

 // Flickr検索終了後のコールバック関数
 function jsonFlickrApi ( data ) {
    alert("jsonFlickrAPI called");
    var list=data.sizes.size;
    var msize=list.find(
                function(obj,index) {
                 return obj.label == "Medium";
                }
              );
    alert(msize.source);
 }
-->
</script>

2007年6月2日

Javascript上でのオブジェクト・データベース
prototype.jsとJSONで


ソース:

<script src="prototype.js" type="text/javascript"></script>
<script>
//データベースの作成
 var objDB = new Array();
 objDB.push( { id: '235', value: '二百三十五' } );
 objDB.push( { id: '372', value: '三百七十二' } );
 objDB.push( { id: '102', value: '百二' } );

//データベースの内容を表示
 objDB.each(
  function( obj, index ) {
    document.write(
      "objDB["+index+"]:"
      +"obj.id="+obj.id+","
      +"obj.value="+obj.value"
      + "<BR/>"
    );
  }
 );

//データベースの内容を検索する関数
 function get( id ) {
  return
   objDB.find(
    function( obj, index ) {
      return obj.id == id;
    }
   );
 }

//データベースの検索を実行
 var resultObj = get( '372' );
 document.write("id=372のvalueは"+resultObj.value );
</script>

元ネタ:Javascriptにおける配列と連想配列 prototype.js編 その1 @GreenSpace