【プログラミング】JavaScript:onloadイベントの多重化に対応する

「肉離れ」の記事を何日も続けてしまいました。その甲斐あってというわけではないですが、家に引きこもった休日であったため、私のWebサイト「新館」のメンテナンスを少し進めることができました。今回は、一部Ajax化を進めてみましたので、そのためのイベント処理方法の改善など、書いてみたいと思います。

Shinkan_photo_04

冒頭の画面は、この記事の執筆時点の「写真館(花と植物の写真館)」のようすですが、写真の下に茶色い字で簡単な説明を表示しています。この説明文は、「Flickr」に書いたものをWebサービスを呼び出して引っ張ってきているのですが、サービスの呼び出しが複数回にわたるので、ページ表示上の大きなオーバヘッドになります。写真の枚数が多くなるほど、ページの表示までに時間がかかるようになります。

そこでAjaxを導入し、ページ表示後に非同期にFlickrから説明文を取得し、ページの該当箇所を動的に書き換える、ということをやってみます。実はこれは非常に簡単なことで、ページのbody要素のonloadイベントに、このような処理をするJavaScriptコードを書いてあげるだけです。

ですが今回は、このJavaScriptコードの中身は重要ではありません。それよりも、onloadイベントに複数のハンドラを登録する方法、そちらの方が重要なのです。ちなみに、これまではこんな感じで書いていました。

<body onload="init()">
………
</body>

マスターページを使用しているので、このコードはマスターページ側にあります。実際のコンテンツ側では、このinit()をオーバライドし、独自の初期化コードを組み込むようになっています。

<script type="text/javascript">
    //<![CDATA[
    function() {
        init = function() {
            初期化するコード
        }
    }
    //]]>
</script>

ところがこの方法、この処理を1箇所で行うだけならいいんですが、複数箇所になる場合(たとえばこのような処理を行うユーザコントロールが複数ある、など)には使えないですね。最後の初期化コードだけが有効になってしまいます。とすると、どこか1箇所に初期化コードをまとめる必要があり、すこぶる都合が悪いです。

ということで、onloadイベントに、複数のハンドラを設定できないかと調べたのですが、案の定できました。こちらのブログは、現在は更新を停止しているようなのですが、いろいろ有用な情報があり、助かります。

Javascript onloadが複数ある場合の対処法 ~FancyZoomとCubeブログシールを共存させる : ブログ・カスタマイズ徒然記

この記事にあるとおり、onloadイベントにハンドラを追加する関数を作り(関数の内容は、この記事の参照先にありましたので、それをそのまま利用させてもらいました)、それを別ファイルに保存し、scriptタグで読み込むようにして、あとは個別の初期化関数をその関数を使って登録してやればOKのようです。

たとえば、Fancyboxで画像をズームアップさせるコードと、Google Mapsで地図を表示させるコードをonloadイベントに登録するとしましょう。こんな感じです。

<asp:ScriptManagerProxy id="smp" runat="server">
    <scripts>
        <asp:ScriptReference Path="../js/utils.js"></asp:ScriptReference>
    </scripts>
</asp:ScriptManagerProxy>

<script type="text/javascript">
    //<![CDATA[

    function setupAlbumImage() {
        $(‘a.album’).fancybox();
    }
    addOnloadEvent(function () { setupAlbumImage(); });

   var mapdiv = $get(‘maps’);
        if (mapdiv != null) {
            ………
        }
    }
    addOnloadEvent(function () { setupGoogleMaps(); });
    //]]>
</script>

ScriptManagerProxyコントロールでutils.jsというスクリプトを読み込んでいますが、ここにonloadイベントに関数を登録する関数addOnloadEvent()が書かれています。scriptタグ内では、この関数を2回呼び出し、onloadイベントへの登録を行っています。

ということで、どこでもbody要素のonloadイベントに関数を設定し、呼び出すことができるようになりました。これによって、jQueryのプラグインやAjaxの使用がすごくやりやすくなります。これから「新館」もAjax化をどんどん進めていきます。ASP.NETのサイトは得てして重くなりがちなので、使い勝手もよくなることが期待できます。

ちなみに、このテクニックはASP.NETに限らず応用できます。上記サイトの記事は非常に参考になりました。ありがとうございます。

コメント