2008年3月31日月曜日

prototype.js を使ったスターレイティング(JavaScript 星評価)

YouTube や Amazon、livedoor Reader でコンテンツの評価に使われているスターレイティングを prototype.js を使って割と汎用的に実装してみました。

http://www.masugadesign.com/the-lab/scripts/unobtrusive-ajax-star-rating-bar/
などには高機能なライブラリがあるようですが、とっつきにくいので自作しました。順を追って説明していきます。

準備と前提条件:
  1. prototype.js(今回は ver1.6)を使用します。 http://prototypejs.org/ からソースをダウンロードしておきましょう。
  2. 5段階の星を表現するために、未選択のものを含めて 6つの画像が必要です。私は http://iconlet.com/ から素材を入手してペイントで加工しました。(サンプル:、使った素材のライセンスはコチラ http://creativecommons.org/licenses/by-sa/3.0/)


上記 2つの準備が終わったら、starrating.js を作成します。計算部分は livedoor Reader を参考にさせていただきました。
StarRating = Class.create({
initialize: function(id, images, options) {
var img = $(id);
Event.observe(img, "mousemove", function(e) {
if (!img.getAttribute("orgSrc")) {
img.setAttribute("orgSrc", img.src);
}
var width = img.offsetWidth;
var cell = width / images.length;
var offsetX = !isNaN(e.offsetX) ? e.offsetX: e.layerX - img.offsetLeft;
// Position.cumulativeOffset(img)[0]
if (offsetX == 0) offsetX++;
if (offsetX > width) offsetX = width;
var rate = Math.ceil(offsetX / cell);
if (rate < 1) {
rate = 1;
}
if (options.basePath) {
img.src = options.basePath + images[rate - 1];
} else {
img.src = images[rate - 1];
}
img.setAttribute("rate", rate);
});
Event.observe(img, "mouseout", function(e) {
var src = img.getAttribute("orgSrc");
if (src) {
img.src = src;
}
});
if (options.onClick) {
Event.observe(img, "click", function(e) {
img.removeAttribute("orgSrc");
options.onClick.call(this, img, img.getAttribute("rate"));
});
}
}
});

prototype.js, starrating.js、星画像を次のようにウェブサーバに配置します。
  • /js/prototype.js
  • /js/starrating.js
  • /img/rate0.png
  • /img/rate1.png
  • /img/rate2.png
  • /img/rate3.png
  • /img/rate4.png
  • /img/rate5.png

そして最後にスターレイティングを呼び出すコードを書きます。
<script src="/js/prototype.js" type="text/javascript"></script>
<script src="/js/starrating.js" type="text/javascript"></script>
<img src="/img/rate0.png" width="80" height="16" id="starRating" />
<script language="javascript" type="text/javascript">
new StarRating(
"starRating",
["rate1.png", "rate2.png", "rate3.png", "rate4.png", "rate5.png"], {
basePath: "/img/",
onClick: function (img, rating) {
alert(rating);
}
}
);
</script>

まず、img 要素で rateX.png を定義します。このとき、id には任意の名前を指定してください。サンプルでは "starRating" を使っています。次に、script タグの中で StarRating を 生成します。第一引数は img 要素の id、第二引数は、マウスオーバーで切り替える画像の配列を指定します。第三引数のオプションでは basePath と onClick コールバック関数を指定することが可能です。onClick コールバック関数の引数は img 要素と算出されたレイティングです。

サンプルは alert しているだけですが、実際には Ajax.Request 等を用いてサーバ側にユーザがどの星をクリックしたかを送信することになると思います。

0 件のコメント: