SimpleBoxes

月を撮影してみる

ちょっと雲が出ていましたが、そこそこ奇麗に月が見えていたので、写真を撮ってみました。

月は明るいですね。今回、満月ではありませんでしたが、そのまま撮影すると、あっさり白飛びします。

そこで、空の様子は「黒つぶれ」してしまっても構わないと割り切って、露出補正を -2EV に設定して撮影してみました。

手持ちだとブレるので、三脚 + タイマー撮影して、ブレないようにしています。

[写真] 今回撮影した月

できるだけ解像感が欲しいので、普段は 5M に設定している記録画素数を 9M に設定しました(使用機種は FinePix S9100)。

月の周辺を正方形でトリミングした上で、リサイズしています。

個人的には初めてにしては、思ったよりもしっかり撮れた感じ。もうちょっと寄れると良いんでしょうけど、35mm 換算で 300mm だとこんなもんでしょうか。

スポンサーリンク

iPod touch の機能ガイド

iPod touch 機能ガイド

iPod touch には「クイックスタート」と「この製品についての重要なお知らせ」という小さい小冊子しか添付されていません。

「機能ガイド」と呼ばれる詳細なマニュアル(82ページ)は、アップルのサポートページに用意されています

ダウンロードして、一度目を通しておくといいかもしれません。

この PDF 文書、iPod touch で読めると便利なような気がしますが、標準の機能では、おそらく PDF 文書は読めない感じ。「iPod touchでWebをオフライン閲覧してみたい - Underconstruction by Taiyo@hatena」で紹介されていた方法を使って、写真として PDF を取り込んでみましたが、字がつぶれてしまって実用には堪えませんでした。

以下、2007/10/23 に追記

よく考えたら、Safari で PDF の表示が可能ではないかと思って、上述の PDF 書類を表示させてみました。

PDF の表示はできたのですが、PDF 表示に日本語が考慮されていないらしく、日本語の部分は軒並み空白で表示されてしまいます。現状では、ちょっと使えない様子。英語文書は、ばっちり表示されます。

iTunesで PDF 書類を取り扱えるので、iPod touch でもきちんと取り扱えるようになってほしいなぁ。

スポンサーリンク

iPod touch がやってきた!

[写真] iPod touch 外箱こちら、ニュージーランドでもぼちぼち入荷し始めた様子の iPod touch ですが、私の手元にも友人経由でやってきました。

これまで正直なところ、iPod を欲しいと思ったことがありませんでした。

今年の始めに発表された iPhone に関しては、一目でインタフェースに惹かれて、是非触ってみたいと思っていました。

ただ、私の携帯電話の使用頻度を考えると、無用の長物になりそうな印象で、触ってみたいけれども購入することはないだろうな、とも思っていました。

ちなみに携帯電話については、今は Nokia 1100 (Nokia 1100 - Wikipedia) という端末を利用しています。この端末についている懐中電灯機能が、何気に利用価値が高くて、結構重宝していたりします。

そこへ iPod touch が登場して、iPod に興味がなかった私も、これはいいんじゃん?となった訳です。

ニュージーランドは iPod に限らず、Apple 製品の入荷は遅くて、入荷数も限りがあることが多いです。

また、値段も日本やアメリカに比べるとやや高め。

今回、たまたま友人がアメリカに行っていて、「欲しいものあったら買っておくよ?」と言ってくれたのがきっかけとなり、私の誕生日も近かったので、今年の誕生日プレゼントとして購入することになりました。

で、それが昨日手元に届いた訳です。

第一印象は、箱小さっ!

[写真] iPod touch 外箱比較一般的な VHS ビデオパッケージより iPod touch の箱の方が小さい

店頭で iPod nano や iPod shuffle のケースは見たことがあって、iPod touch の箱はそれよりは大きいのですが、予想していたよりもはるかにコンパクトでした。

はやる気持ちを抑えつつ、箱を開けて iPod touch とご対面。

[写真] iPod touch とご対面

薄い!

iPod touch のスペックを見て、その薄さは一応認識していたつもりでしたが、やはり薄い。薄いけど持ってみると、思ったよりもずしりとくる感じで、薄っぺらいという印象は全くありません。

早速、手元の MacBook と同期させて、色々いじってみました。

う〜む。見せ方が巧い

思わずうなってしまう程。アニメーション・グラフィックの描画速度に関しては、従来のモバイル端末とちょっと次元が違うような印象です。

主に画面スクロールで利用する「フリック」と呼ばれる指で弾くようなタッチ操作がありますが、速度調整が絶妙で、かなり気持ちよく操作できます。写真のサムネイル画面のスクロールなど、ちょっと尋常じゃない速度で描画していて、ただスクロールさせるだけでも楽しい

[写真] SimpleBoxes in iPod touch

iPod touch に搭載されている Safari は、いわゆるフルブラウザになります。表示するページによっては動作がやや不安定になる印象がありますが、モバイル用のブラウザとしては、かなり高性能なブラウザと言ってしまって良いんじゃないでしょうか。

私のネットワーク環境だと、ウェブページが描画されるまでやや待たされる印象があります。MacBook と比較するとやはりやや遅めですね。

しかしながら、何よりも手軽さがあるので、ちょっとページを確認したいって時には結構便利。ごろ寝ウェブサーフィンにはもってこいです。

個人的な印象ですが iPod touch の Safari に対しては、1 カラムなデザインの方が閲覧しやすくなる感じがします。

残念ながら、ファイルのアップロード (input 要素の type 属性が file なフォーム) は、利用できませんでした。その他のフォーム要素に関してはおそらく一通り動作するので、ウェブログの記事投稿なども iPod touch からできそうです。

iPhone の Safari と比較して、どの程度機能差があるのかも気になるところ。少なくとも iPod touch のカレンダーは iPhone のそれと比較すると、機能が劣っている様子です。

既報の通り、iPod touch では日本語入力が可能です。POBoxライクな入力方法(っていうか、制作者は同じ人!)で、助詞・助動詞を推測表示してくれたりして、キーボードの入力数が結構押さえることができる印象。効果的に学習もしてくれる様子です。

結構入力が快適なので、長文をがーっと入力してもいけそうな感じですが、以下の二点が改善されるともっと快適かも……。

  • コピー・ペーストができない
  • アンドゥができない

コピー・ペーストは欲しいところですが、現状のインタフェースを考えると実装は難しい気も……。

アンドゥは欲しいです。間違って多く消しちゃったりした時がつらい。あと誤入力を間違って確定しちゃったりした時とか。

あと、日本語入力中は、縦画面のおよそ半分が入力パネルで埋まってしまいます。実質的な表示領域が圧迫されてしまので、文章全体を見通すのに不利かもしれません。

すでに色々と HACK も出ている iPod touch ですが、とりあえず当面はデフォルトのままで利用しようかと思っています。

ちなみに当ページはTravellers Tales : ウェブサイトを iPhone/iPod touch 対応にする最も簡単な方法を参考にして、iPod touch/iPhone 向けの最適化設定を追加しています。

スポンサーリンク

mixi デザインリニューアルに関してのご意見

こんな回答で良いの

そもそも質問者が mixi のリニューアルに否定的な目で見ているのでアレ(どれ?)なんですが……。

これはあくまでも、このウェブサイトの立ち位置や、これまでの流れ・仕組みなどは考慮せず、このページを見ただけの感想でしかありません。念のため。

特に二番手の回答者、寺田あつし氏の回答にかなりびっくりしました。

いまだにphpではなくperlで動いているあたり

なんて発言も正直「どうかしてる」としか言いようがないんですけど、

情に流され、経営者としての判断を誤った社長

とか今回のリニューアルと関係あるの?

三番手の回答者、谷口浩一氏の意見だと、

今回のリニューアルで一番の問題は、横幅が200ピクセル少々増えて、横スクロールが発生してしまう利用環境がすごく増えたこと

それが「一番」問題なんだろうか?

私には、以前にはユーザー側で 2 or 3 カラムが選択可能であった仕様が変更されてしまった、というのが一番大きいと思うんだけど。

スポンサーリンク

ユーザースタイルシート for mixi

リニューアル後のmixiを2カラム/750px幅化するユーザースタイルシートを書いてみたで公開されているユーザースタイルシートをベースに自分向けにカスタマイズしてみました。

User CSS for mixi

変更点は以下の通り。

  • コンテンツがセンタリングされるように
  • ナビゲーションバーの長さが大体 750px になるように
  • 最新情報のタイトル・コンテンツのデザインを旧デザインっぽく?
  • プルダウンメニューが利用できるように
  • ロゴを何となく復活させてみた

グローバルナビゲーションの画像はリサイズしているので、Windows だと汚くなります。

[2008.03.26 追記] 2008.03 にこっそりと mixi のデザインが変更になったことを受けて、スタイル内容も変更しました。

@namespace url(http://www.w3.org/1999/xhtml);

@-moz-document domain("mixi.jp") {

/* original code by http://www.akiyan.com/blog/archives/2007/10/mixi2765px.html */

body {
  width:750px !important;
  margin-left: auto !important;
  margin-right: auto !important;
}

/* ロゴ */
h1 {
  width:750px !important;
  margin-left: auto !important;
  margin-right: auto !important;
}

/* 広告バナー非表示 */
.adBanner {
  display:none !important;
}

/* 右カラム非表示 */
#bodySub { display:none }

/* ヘッダの背景を透過色に */
#headerArea {
  width:750px !important;
  margin-left: auto !important;
  margin-right: auto !important;
}

/* ヘッダエリアの幅調整 */
#headerArea {
  width:750px !important;
  margin-left: auto !important;
  margin-right:: auto !important;
}

/* ヘッダの高さを自動に */
#headerArea { height:auto !important }

/* 本文エリアの幅調整 */
#bodyArea {
  width:750px !important;
  margin-left: auto !important;
  margin-right: auto !important;
}

/* グローバルナビゲーションの幅調整 */
#globalNavigation {
  width:750px !important;
  margin-left: auto !important;
  margin-right: auto !important;
}

/* グローバルナビゲーションのmikly・動画・フォトボタン非表示 */
#globalNavigation ul.contentsNavigation li {
  width: 57px !important;
  height: 28px !important;
}
#globalNavigation ul.contentsNavigation li.home {
  width: 66px !important;
}

/* ローカルナビゲーションの幅調整 */
#localNavigation {
  width: 750px !important;
  margin-left: auto !important;
  margin-right: auto !important;
}
#localNavigation ul li {
  height: 20px !important;
}
#localNavigation ul.localNaviHome li {
  width: 73px !important;
}
#localNavigation ul.localNaviFriend li {
  width: 79px !important;
}
#localNavigation ul.localNaviCommunity li {
  width: 89px !important;
}
#localNavigation ul.localNaviNews li {
  width: 65px !important;
}

/* ローカルナビゲーションのプルダウンボタン非表示 */
#diaryPullDownButton,
#videoPullDownButton,
#photoPullDownButton,
#reviewPullDownButton,
#eventPullDownButton,
#topicPullDownButton {
  display: none !important;;
}

/* フッター幅調整 */
#footerArea {
  width:750px !important;
  margin-left: auto !important;
  margin-right: auto !important;
}

/* フッターナビゲーションマージン調整 */
#footerArea ul.footerNavigation01 li {
  margin:0 2px !important
}

/* 検索フォーム非表示 */
div.searchForm01{
  display:none
}

/* 「最新情報」ヘッダの非表示 */
#mymixiUpdate div.heading01 { display:none }

/* 最新情報タイトル */
#bodyContents div.heading02 {
/*
  background: transparent url(http://img.mixi.jp/img/basic/heading/body_contents001.gif) no-repeat scroll 0% !important;
  height: 28px !important;
*/
}

/* 最新情報コンテンツ */
#bodyContents div.contents {
  background-color: #f8f8f8 !important;
  border: 1px solid #DFB479 !important;
}
#bodyContents div#myUpdate div.contents,
#bodyContents div#intro div.contents {
  background-color: transparent !important;
  border: 0px none #DFB479 !important;
}
#bodyContents div.contents dl {
  margin: -1px !important;
}

/* 自身の最新情報・友人紹介文 */
#myUpdate div.heading01,
#intro div.heading01 {
/*
  background:  transparent url(http://img.mixi.jp/img/basic/heading/body_contents002.gif) no-repeat scroll 0% !important;
  height: 28px !important;
  width: 442px !important;
*/
}

}

スポンサーリンク

BEGIN ブロックではまる (perl)

表題の通り、BEGIN ブロックの扱いではまったので、忘れないようにメモ。

package test;
use vars qw( $CHECK );
$CHECK = undef; # 初期化
BEGIN {
  eval { require test::optional; };
  $CHECK = 1 if (!$@); # optional モジュールを呼び出せたので、フラグを立てる
};

上記のようなコードを記述していたのですが、意図した通り動いてくれていませんでした。

BEGIN ブロック内では、$CHECKは「1」になっているのですが、後から(例えば、test モジュールを要求したモジュールから)参照すると、$CHECKが未定義に見えます。

BEGIN ブロックが存在した場合、そのコードは真っ先に実行されます。その後、BEGIN ブロック外のコードが、必要ならば、実行されます。

そのため、BEGIN ブロックで「1」になった $CHECK は、その後、 「$CHECK = undef; # 初期化」と記述された行が実行されることにより、未定義になります。「初期化」と書かれながら、初期化になっていませんでした。

正しくは、以下の通り。

package test;
use vars qw( $CHECK );
BEGIN {
  $CHECK = undef; # 初期化
  eval { require test::optional; };
  $CHECK = 1 if (!$@); # optional モジュールを呼び出せたので、フラグを立てる
};

基本っぽいことですが、すっかりはまってしまっていました。

スポンサーリンク

WebKit で CodePress を利用するために

CodePress (http://codepress.org/) は、ウェブブラウザ上で HTML や JavaScript などのソースを編集するために、文法カラーリングなどをサポートする便利なスクリプトです。

CodePress in Safari

Movable Type 4 では、テンプレートエディタとして利用されていて、Serene Bach 3 でも大いに利用しています。

CodePress の最新リリースバージョンは v 0.9.5 ですが、サポートされているブラウザは Firefox (Mozilla系ブラウザ)、Internet Explorer for Windows、Opera となっています。Safari は残念ながら、現時点では対象外です。

ざっと調べてみましたが、基本的な機能(文法カラーリング)ならば、Safari でも動作させることができます→CodePress 動作サンプル

Onload イベント

Firefox と Opera では、DOMContentLoaded イベントをトリガーにして CodePress を起動させています。

このイベントは Safari ではサポートされていません。従って、DOMContentLoaded の代わりに load イベントを利用します。

contentWindow の挙動の差異

CodePress では、textarea 要素にかぶせるようにして iframe 要素を配置して、その中で独自のエディタを動作させます。

iframe 要素で動作させたエディタの内部情報を取得するのに contentWindow プロパティを利用しています。

contentWindow は Safari 2.0 でも動作するのですが、その挙動が若干 Firefox などとは異なるため、iframe 内部の情報を正しく取得することができません。

codepress.js では、以下のようにして iframe で定義された CodePress オブジェクトを取得しています。

self.editor = self.contentWindow.CodePress;

[note] ここで、self は CodePress で作成した iframe 要素の DOM オブジェクトです。

self.editor には、iframe 内部で生成された CodePress オブジェクトが入って、内部の setCode やら syntaxHightlight やらのメソッドをコールできるようになります。

self.editor.setCode(self.textarea.value);
self.editor.syntaxHighlight('init');

ところが、Safari では、self.editor.setCode が関数ではないと怒られます。ontentWindow 自体はきちんと認識されているにもかかわらず、それを変数に代入すると参照できなくなってしまうような印象です。

ですので、Safari では、self.editor を利用するのではなく、常時 contentWindow を介して内部関数をコールしてあげる必要がある様子です。

self.contentWindow.CodePress.setCode(self.textarea.value);
self.contentWindow.CodePress.syntaxHighlight('init');

getSelection と getRangeAt

Safari では、Firefox 同様、window.getSelection が利用できます。

Firefox では、以下のようなコードで、選択された範囲の DOM Range オブジェクト range を取得できます。

var range = window.getSelection().getRangeAt(0);

しかしながら、Safari では、getSelection で取得できる DOM Selection オブジェクトが getRangeAt というメソッドを持っていないようです

[note] Safari 2.0.4 でのみ確認。Safari 3.0 では確認していません。

そこで、Safari では以下のようなコードで選択された範囲の DOM Range オブジェクト range を取得します。

var selection = window.getSelection();
var range = window.document.createRange();
range.setStart(selection.baseNode, selection.baseOffset);
range.setEnd(selection.extentNode, selection.extentOffset);

designMode で編集された内容

Safari では、Firefox 同様、iframe の属性として、designMode = 'on' をセットすることで、iframe の内容を編集可能にします。

CodePress では、マークアップはシンタックスカラーリングのためだけに利用されます。

そのため、syntaxHightlight メソッドで、シンタックスカラーリングを行う際に、一度編集された内容を復元して、マークアップし直すという操作が行われます。

designMode を変更して、編集モードになった時に、Safari では、改行挿入時に行われる操作が Firefox とは異なるため、そのままでは適用できません。

具体的には以下のような操作になるようです。

  • 一回目の改行では、ブロック分け操作になる。そのため空の div 要素が挿入される。
  • そのまま二回目の改行では、br 要素が挿入されるが、class 属性として、khtml-block-placeholder (Safari 3.0 では webkit-block-placeholder) が指定されている。

そのため、改行コードのバッファリング操作が Firefox とは異なります。

iframe に対するスタイル指定

CodePress では、iframe の読み込みを行う前に iframe のスタイルに関して position プロパティを absolute に指定しています。

挿入される iframe によって、textarea がずれてしまう現象を防ぐために行っているようです。

Safari 2 だと、position プロパティを absolute から static に変更すると、何故か iframe を再度読み込んでしまう現象が発生します。

これを防ぐためには position プロパティを最初から static にしておくという対処が考えられます。

ちなみにこのバグ(?)は Safari 3 では修正されているようで、Safari 3 では、この修正をする必要はありません。

更なる問題

ここまでの対応で、とりあえず CodePress の基本的な動作は実現可能になります。

しかしながら、CodePress 起動後の CodePress へのアクセスなどまだ解決すべき問題が残っています。

また、安定性も今ひとつで、特に undo 操作を行うと簡単にブラウザが落ちます。普通に利用する分には問題なさそうですが。

スポンサーリンク

[perl]ハッシュ(連想配列)のマージ

perlのハッシュ(連想配列)のマージについてちょっと調べました。自分用のメモとして記録しておきます。

一番直観的な方法は以下のようなコードでしょう。

%hash = (%hash, %addition);

ハッシュ %hash に対して、%addition の内容を追加します。

my %hash = (
  'key1' => 'value1',
  'key2' => 'value2',
);
my %addition = (
  'key3' => 'value3',
  'key4' => 'value4',
  'key1' => 'override1',
);
%hash = (%hash, %addition);

上述のようなコードを実行すると、%hash の内容は以下のようになります。

  'key1' => 'override1',
  'key2' => 'value2',
  'key3' => 'value3',
  'key4' => 'value4',

key1 の内容が上書きされているのがポイント。

whileforeach でループを回してハッシュをマージする方法も利用できます。

whileeach を組み合わせると、以下のようなコードになります。

while (my($key,$val) = each (%addition))
{
  $hash{$key} = $val;
}

foreachkeys を組み合わせて、以下のような方法でもマージできます。

foreach my $key (keys %addition)
{
  $hash{$key} = $addition{$key};
}

同様の操作は map を使っても可能です。

map { $hash{$_} = $addition{$_} } keys %addition;

最後にスライスを使う方法もあります。スライスを使い慣れた人には、ぱっと書けると思うのですが、私にはすぐには書けませんでした。

@hash { keys %addition } = values %addition;

%hash ではなく、@hash と記述します。

ハッシュのリファレンスを利用した場合も同様に記述できます。

# normal merge
$hash = {%{$hash}, %addition};
# use while
while (my($key,$val) = each (%addition))
{
  $hash->{$key} = $val;
}
# use foreach
foreach my $key (keys %addition)
{
  $hash->{$key} = $addition{$key};
}
# use map
map { $hash->{$_} = $addition{$_} } keys %addition;
# use slice
@{$hash} { keys %addition } = values %addition;

速度がどの程度違うのか、調べてみました。

利用したコードは「続き」に記載しています。

foreach:  4 wallclock secs ( 4.17 usr +  0.00 sys =  4.17 CPU) @ 119904.08/s (n=500000)
    map:  5 wallclock secs ( 3.96 usr +  0.00 sys =  3.96 CPU) @ 126262.63/s (n=500000)
  merge:  7 wallclock secs ( 6.66 usr +  0.01 sys =  6.67 CPU) @ 74962.52/s (n=500000)
  slice:  5 wallclock secs ( 4.32 usr +  0.01 sys =  4.33 CPU) @ 115473.44/s (n=500000)
  while:  5 wallclock secs ( 4.35 usr +  0.01 sys =  4.36 CPU) @ 114678.90/s (n=500000)

使うなら、map でしょうか。

スライスを利用した方法も、マージするハッシュの内容によって速くなる場合がありましたが、具体的な条件が分かりませんでした。

従って、手元の簡単な調査では map によるマージが比較的安定した結果を出すという印象です。

続きを読む

スポンサーリンク

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

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 座標に関してもほぼ同様な方法で取得できます。

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

スポンサーリンク

スター

本エントリとはてなスターは、関係ありません。

クリックしても何も起きませんので、あしからず。

とりあえず、javascriptとCSSの実装はこんな感じ?でしょうか。

スタイルシートが更新されているので、もしマウスオーバーで星の数が変わらなかったら、リロードしてみて下さい。

[2007/07/26] 追記

とりあえず、評価投稿処理も追加して形にまとめてみました。

ですので、上で置いていた試作スクリプトは削除しています。

機能の割に仕掛けなどやや大げさな感じもしますが、こんなもんでしょうか。

仕組みについては後日時間があれば、触れたいと思います。

スポンサーリンク

18/25