SimpleBoxes

記事評価スクリプトの概要

Serene Bach 用プラグイン「記事評価」を公開しました

Serene Bach のプラグインとして公開していますが、内部の仕組みは Serene Bach の機構とはほぼ独立しています。

ここ、SimpleBoxes は諸事情により Serene Bach ではなく、sb で運用していますが、プラグインという形ではなく、独立した形で導入しています。

記事評価スクリプトは、主に以下のパーツからなっています。

sbstar-script.js
インタフェース処理を行う JavaScript
rating.cgi
投稿された評価の受付処理を行う CGI スクリプト
sbstar.txt
投稿された評価内容を保存するテキストファイル
その他
スタイルシートや画像パーツなど「見た目」を構成するリソースファイル

スタイルシート

記事評価を表示する方式としては、スターレーティングをCSSでデザインするのようなものもありますが、「平均値を表現するのには向いていない」「HTMLファイルの更新を行いたくない」という理由により、JavaScriptで幅を指定する方式を採用しています。

具体的には以下のようなHTMLとCSSを利用します。

<p class="sbrating"><span id="sbstar_id">
「サンプル記事」の評価です。
</span></p>

マークアップ

/* [entry rating extra style sheet] */
.sbrating {
  display: block;
  width: 100px;
  height: 20px;
  background-image: url(sbstar-back.gif);
  background-repeat: no-repeat;
  background-position: 0% 0%;
}
.sbrating span {
  display: block;
  width: 0px;
  height: 20px;
  overflow: hidden;
  background-image: url(sbstar-active.gif);
  background-repeat: no-repeat;
  background-position: 0% 0%;
  text-indent: -9999px;
}
.sbrating span.hover {
  background-image: url(sbstar-hover.gif);
}
ul.status {
  clear: right;
}

スタイルシート

.sbrating spanの幅が「0px」になっていますが、これはJavaScript側で制御するためです。

これで土台となる表示部の実装は終了で、後はJavaScriptで条件に応じて幅を変えてあげればよいだけになります。

動作の流れ

記事評価スクリプトは、以下のような流れで動作します。

  1. HTML ロードに伴い、sbstar-script.js がロードされる。
  2. 評価を表示する要素( class 属性が sbrating である要素)を確認して、初期化する。
  3. sbstar-script.jsより、XMLHttpRequestを起こして、sbstar.txtを呼び出す(Ajax)。
  4. 該当する id が存在する場合には、評価部分をアップデートして、評価値を表示する。
  5. 記事評価がクリックされたら、受付処理を行うスクリプトに評価値を渡す(Ajax)。
  6. 受付処理でデータを更新したら、処理終了通知を返す。
  7. 3. に戻る。

受付処理は CGI スクリプトですので、そこだけ動的に処理されます。逆に言えば、受付処理が行わなければ、ブラウザからは静的に生成されたファイルにしかアクセスされません。

この過程では、HTMLファイルの更新は行われないようにしています。sb/Serene Bach では、ひとつの記事がひとつの HTML ファイルだけに存在するとは限らないので、HTML ファイルを更新するプロセスをいれると、どうしてもその分重くなってしまう可能性を捨てることができません。

Serene Bach「記事評価」プラグインでは、管理画面で評価された記事の情報を確認することができます。これも受付処理で更新されたプレーンテキストのデータ(sbstar.txt)を読み込んで整形処理しているだけです。

mouse over/move イベント処理

JavaScriptの処理として、ポイントとなるのは、mouse over の処理でしょうか。

上記手順、2. の初期化の段階で、該当する要素(記事評価を表示する要素)に対して、マウスイベントを処理する関数を登録します。

該当要素にマウスカーソルが当たっているときには、マウスカーソルの位置に応じて星の数を変化させる必要があります。

この時、対象とするマウスカーソルの位置は、あくまでも要素内での相対的な位置だけを取得する必要があります。

ブラウザウィンドウ内でのマウスカーソルの位置は event.clientX(event.clientY) で取得できますが、あくまでもウィンドウ内での位置です。これに対して、対象要素の表示位置を考慮する必要があります。

ここで event とは、イベントハンドラに引数として渡される変数ないしは window.event で取得できる、イベントオブジェクトを指しています。

対象要素が絶対配置されている場合は、offsetLeft プロパティを利用すれば、ほぼ取得可能です。しかしながら、対象とする要素が、必ずしも絶対配置されているとは限りません。むしろそうでないケースの方が多いでしょう。

そこで、要素の位置を以下のようなコードで取得します。Internet Explorer 6.0以降, Safari 2.0以降, Opera 9.0, Firefox 2.0 で動作を確認しています。

  var x = obj.offsetLeft;
  var parent = obj.offsetParent;
  while (parent)
  {
    x += parent.offsetLeft;
    parent = parent.offsetParent;
  }
  return x;

ここで、obj は、対象とする DOM オブジェクトを指します。

offsetParent プロパティは、表示位置に関連している親 DOM オブジェクトを返します。これをルートまで辿っていけば、最終的な表示位置を取得できるという仕組みです。

上記サンプルコードでは、x 座標のみを対象としていますが、y 座標に関してもほぼ同様な方法で取得できます。

これで得られた対象要素内でのマウスカーソル位置を利用して、対象要素の幅を動的に変えてあげれば、★の数の表示が可能になります。

スポンサーリンク

<< スター :: [perl]ハッシュ(連想配列)のマージ >>