SHOEISHA iD

※旧SEメンバーシップ会員の方は、同じ登録情報(メールアドレス&パスワード)でログインいただけます

DeveloperZine(デベロッパージン)- エンジニアの意思決定を支える技術情報メディア ProductZine

CodeZine編集部では、現場で活躍するデベロッパーをスターにするためのカンファレンス「Developers Summit」や、エンジニアの生きざまをブーストするためのイベント「Developers Boost」など、さまざまなカンファレンスを企画・運営しています。

japan.internet.com翻訳記事

Facadeデザインパターンを利用したオブジェクト指向JavaScriptカレンダーの作成

月ごとの画像表示が可能なJavaScript+CSSによるカレンダー

ドキュメントオブジェクトメソッドの記述

 各テーブルセルに、changeDate()という関数をポイントするonClickイベントハンドラと、changeMonth()という関数を呼び出す4つのナビゲーション文字列が含まれていることに気付いた人もいるのではないでしょうか。この2つの関数は、カプセル化というオブジェクト指向の原則に反しても、カレンダーオブジェクト外に宣言する必要があります。なぜなら、この2つの関数が取り扱うイベントは、カレンダーオブジェクトではなく、ドキュメントオブジェクトによって発行されるからです。

 このプロジェクトでは、現在のカレンダーオブジェクトへの参照を取得するために、JavaScriptのトリックをいくつか使用しています。基本的には、eval()関数を通じて引数を渡すことで、文字列パラメータを現在のカレンダーオブジェクトに変換しています。ここで注意したいのは、カレンダーオブジェクトの作成時に渡すidパラメータは、宣言した変数名と同じでなければならないということです。これは現在のカレンダーへの参照を保持するためのちょっとした代償です。changeDate()関数のコードを以下に示します。

function changeDate(td,cal){
   // Some JavaScript trickery
   // Change the cal argument to the existing
   // calendar object
   // This is why the first argument in the
   // constructor must match the variable name
   // The cal reference also allows for
   // multiple calendars on a page
   cal = eval(cal);
   document.getElementById(cal.id +
      "selected").className = "days";
   document.getElementById(cal.id +
      "selected").id = "";
   td.className = "date";
   td.id = cal.id + "selected";
   // set the calendar object to the new date
   cal.dateObject.setDate(td.firstChild.nodeValue);
   cal = new calendar(cal.id,cal.dateObject,cal.pix);
   // here is where you could react to a date change?
   // I'll just display the formatted date
   alert(cal.getFormattedDate());
}

 changeDate()関数は基本的に、cal引数をカレンダーオブジェクトに変換した後、td参照を使用して、新しくクリックされた日付に現在の日付のCSSクラスを割り当てます。その後、内部のDateオブジェクトの日付を、クリックされたセルの値で書き換えます。最後に、テストのため、書式設定済みの日付を警告ボックスに表示します。ここではこのような方法を使用していますが、日付の切り替えはどんな方法で実現しても構いません。

 changeMonth()関数では、カレンダーの月を次に進める(または前にさかのぼる)処理を行います。この関数は、先ほど現在のカレンダーオブジェクトへの参照を保持するために使ったeval()関数のトリックを使用しています。ここで嬉しいのは、Dateオブジェクト(ひいてはカレンダーオブジェクト)は月の折り返しを自動的に処理してくれるということです。つまり、「12月の次は1月」、「1月の前は12月」と自動的に判断してくれます。changeMonth()関数のコードを以下に示します。

function changeMonth(mo,cal){
   // more trickery!
   cal = eval(cal);
   // The Date object is smart enough to
   // know that it should roll over in December
   // when going forward and in January
   // when going back
   cal.dateObject.setMonth(cal.dateObject.getMonth() + mo);
   cal = new calendar(cal.id,cal.dateObject,cal.pix);
   cal.formattedDate = cal.getFormattedDate();
   document.getElementById('calContainer').innerHTML = cal.write();
}

 ここまで作成したファイルに「calendar.js」という名前を付け、CSSファイルと同じフォルダに保存します。

HTMLファイルの作成

 ここまでくれば、カレンダーを表示するHTMLファイルの作成は非常に簡単です。必要な処理のほとんどはカレンダーオブジェクトが行ってくれるからです。テキストエディタで新しいファイルを開き、次のHTMLファイルを作成します。

<html>
  <head>
    <title>Calendar Demo</title>
    <script src="calendar.js" type="text/javascript"></script>
    <link rel="stylesheet" type="text/css" href="calendar.css"/>
  </head>
  <body>

    <script language="JavaScript">
    // create the pix array
    var pix = new Array();
    for(i = 0; i < 12; i++){
      pix[i] = new Image();
      pix[i].src = 'images/fractal' + i + '.jpg';
    }
    // Place this script wherever you want your calendar
    // The first argument must match the var name
    var thisMonth = new calendar('thisMonth',new Date(),pix);
    document.write(thisMonth.write());
    </script>
  </body>
</html>

 画像を格納するpix配列は、JavaScriptファイルではなく、HTMLページ上で作成する必要があります。このことは、オブジェクト指向の観点から見ても理にかなっています(カレンダーで使用する画像は各ページに固有のものだからです)。今回のサンプルコードでは、命名規則を設け、forループを使用して画像配列を作成しています。このファイルをCSSファイルおよびJavaScriptファイルと同じディレクトリに保存します。

おわりに

 Facadeデザインパターンは、このアプリケーションにうまく適合します。Facadeデザインパターンを採用することで、JavaScriptのDateオブジェクトで使用できるデータを公開しつつ、Dateオブジェクトそのものを直接操作する必要性を排除し、その機能をカレンダーアプリケーション用にカスタマイズすることができます。

 なお、このカレンダーはchangeDate()メソッド内で複数のW3C DOMメソッドを使用しているため、W3C DOMの仕様に準拠しているブラウザでしか利用できません。Mozilla Firebird 0.7、Opera 7.1、およびInternet Explorer 6でテストした結果、この3つのブラウザすべてで正常に動作しました。

この記事は参考になりましたか?

連載通知を行うには会員登録(無料)が必要です。
既に会員の方はを行ってください。
japan.internet.com翻訳記事連載記事一覧

もっと読む

この記事の著者

japan.internet.com(ジャパンインターネットコム)

japan.internet.com は、1999年9月にオープンした、日本初のネットビジネス専門ニュースサイト。月間2億以上のページビューを誇る米国 Jupitermedia Corporation (Nasdaq: JUPM) のニュースサイト internet.comEarthWeb.com からの最新記事を日本語に翻訳して掲載するとともに、日本独自のネットビジネス関連記事やレポートを配信。

※プロフィールは、執筆時点、または直近の記事の寄稿時点での内容です

Tom Duffy(Tom Duffy)

DevXのJavaScriptライター。コネチカット州ノーウォークのノーウォークコミュニティカレッジ(NCC)の助教授で、Web開発とJavaを専門とする。学内のWebデザインスタジオ「NCC Ventures Lab」のマネージャでもある。電子メールの宛先はこちら

※プロフィールは、執筆時点、または直近の記事の寄稿時点での内容です

この記事は参考になりましたか?

この記事をシェア

CodeZine(コードジン)
https://codezine.jp/article/detail/1345 2007/06/05 14:00

イベント

CodeZine編集部では、現場で活躍するデベロッパーをスターにするためのカンファレンス「Developers Summit」や、エンジニアの生きざまをブーストするためのイベント「Developers Boost」など、さまざまなカンファレンスを企画・運営しています。

新規会員登録無料のご案内

  • ・全ての過去記事が閲覧できます
  • ・会員限定メルマガを受信できます

メールバックナンバー