Home > 技術

技術 Archive

SafariのWebインスペクタはFirebugっぽくウィンドウに統合できる

知らなかった〜。
ゆえにあんまりSafariを開発用ブラウザにしてなかったw

以下のようにWebインスペクタの左下のボタンを押すと。


こんな感じにSafariのウィンドウに統合できるみたい。

でもFirebugの調査みたいに、マウスをもって行った箇所を表示するって機能はまだないのかな?
これがないといちいちhtmlタグから順番に降りていかないといけないから面倒・・・

RhinoでJavascriptの継続を使ってみる

継続と言うとSchemeが有名ですが、Rhinoのドキュメントを読んでいたら「Rhino 1.6R1」から継続が存在してたみたいだったのでとりあえず試してみた。
Rhino 1.6R1 変更ログ

継続とは?

継続と聞くとちょっと小難しいので、まずは軽く説明してみます。
継続とは「ある時点での状態」を変数に格納しておき、そのポイントに後から戻るということが可能になる概念である。

・・・

まったくもって小難しいのでとりあえず以下のSchemeのコードを見ていただきたい。

継続サンプル - Scheme

結果

こぶた
たぬき
きつね
ねこ

[via]
Schemeを作ろう 第3回

このコードではdisplayで文字を出力しているのだが、途中のcall/ccという部分が継続オブジェクトを生成している部分になる。
この継続オブジェクトをx変数にセットしているので、もし後でx変数に入っている継続オブジェクトを実行するとさらに

きつね
ねこ

と文字列が出力される。
このようにあるポイントを変数に記憶させておき後から呼び出せるのが継続になるのだ。

そしてそのときのスコープ内の値も保持されているのでクロージャっぽいですね。
ってかクロージャも継続と言ってもいいのかな?

Rhinoをインストールする

一応Rhinoを使ってJavaScriptの継続を試すのでのインストールを書いておきます。参考までに。
あとボクの環境がMacなのでWindowsの方は適宜読み替えていただきたい。

まずは以下からダウンロードします。
Rhino のダウンロード

そしてRhino Shellが使えるように、環境変数を設定しましょう!

ホールディレクトリにある.bash_profileファイルに以下を追記します。
(CLASSPATHに入れるパスはご自分の環境に合わせてくださいね。)

export CLASSPATH=/code/java/rhino1_7R1/js.jar
alias rhino="java org.mozilla.javascript.tools.shell.Main"

.bash_profileへの追記などは以下を参考にしてみてください。
Mac OS Xで環境変数にPATHを追加する方法

設定が終わったら、ターミナルから

$ rhino

と打つとそのままJavaScriptがirb形式でコードを入力できます。
rhinoから抜けたい場合は「quit()」と入力してください。

継続オブジェクトContinuationを使ってみよう

Rhinoで継続を使う場合は、Continuationというクラスをnewすることから始まります。
Continuationクラスをnewして変数に格納すれば、そこが継続として後から戻るポイントになります。

では実際に使ってみましょう!

このコードを保存してrhinoコマンドで実行します。

$ rhino -opt -1 -f coroutine.js

-opt -1は継続を使う場合に必要で、-fはファイルから実行するという意味になります。
Rhino Shell - MDC

先ほどのSchemeのコードに近い感じですが、showMessage関数を呼ぶとprint関数で順番に文字を出力していきますが、
途中にあるcall_cc関数内でContinuationクラスをnewして継続オブジェクトを返しています。
(ここでreturnされるオブジェクトはfunction型になります。)

そしてshowMessage関数の呼び出しの後に継続オブジェクトを関数として呼び出しています。
ただし継続オブジェクトが実行した後はc変数に入っている継続オブジェクトはundefinedになってしまうので、instanceofで継続オブジェクトかどうか判断しています。
これについては順番に説明して理解してみましょう!

以下にshowMessage関数を呼び出したところから処理の流れを記載してみました。

showMessage関数の呼び出し

文字列の出力(hoge1)

Continuationオブジェクトの生成

文字列の出力(hoge2、hoge3)

instanceofで確認→OK

継続関数オブジェクトの実行

文字列の出力(hoge2、hoge3)

instanceofで確認→NG

よって2回目の継続関数オブジェクトは実行されない

ちょっとややこしいですが、c()で継続関数を実行すると継続ポイントに戻って再度コードを実行していきますが、
再びc()の部分まで実行しようとしているのでそれをinstanceofで阻止している感じです。

また継続オブジェクトには引数を渡すこともできます。
「c("foo");」という感じで呼び出すと、「c = "foo"」と同じになり継続オブジェクトに渡す引数で処理を分岐したりもできます。

JavaScript1.7のyieldに似てる

一見yieldを使うと同じような雰囲気は出てるんですが、継続と少し違うのはyieldはポイントポイントで完全に処理が止まって待っててくれるのですが、
継続は処理をすべて1度実行しちゃいます。

継続とyieldの出力結果を見るとよく理解できると思います。

継続の場合の出力結果

hoge1
hoge2
hoge3
hoge4 ←ここが継続ポイント
hoge5

yieldの場合の出力結果

hoge1
hoge2
hoge3

まとめ

継続をどのようにうまく使うかなど、まだ全然理解できていないのでこれから少し掘り下げて勉強してみたいと思います。
(それならScheme勉強したほうが良さそうですねw)

あとGemmaさんの記事で、サーバーサイドJavaScript(Rhino)の継続でCoroutineを書いてみた - Gemmaの日記
というのがすごく参考になります、2つの関数を交互に実行する協調的マルチタスクな処理実装されています。
すごいっす。

■参考リンク
RhinoWithContinuations - Cocoon Wiki

画像をめくるjQuery Plugin - jStack作りました

画像をめくるjQuery Plugin - jStack作りました

Mootools版のmooStackからインスパイアされてjQuery版を作ってみました。

ただ画像をめくるだけだとつまらないので、トランプのようにシャッフルする機能を入れてみました。
ちょっと面白い動きをするのでなかなか気に入ってます。
遊んでみてください〜!

デモ、詳細は以下からどうぞ。
jStack.js - jQuery Plugin

■他に作ったもの。
画像がグルグル回るjQuery Plugin - jMerrygoround作りました

Macに発音させるsayコマンドでDaftPunkは厳しい

MacWiki - コマンド/say
Macに標準でインストールされているsayコマンドは、引数に与えた文字を読み上げてくれるコマンドです。
この時点でちょっと面白いのですが、さらに声の種類も豊富にあるのでいずれかを選んで発音させることができます。

実際のVoiceは以下のようになっており、結構種類がある。

$ ls /System/Library/Speech/Voices/

Agnes.SpeechVoice
Albert.SpeechVoice
Alex.SpeechVoice
BadNews.SpeechVoice
Bahh.SpeechVoice
Bells.SpeechVoice
Boing.SpeechVoice
Bruce.SpeechVoice
Bubbles.SpeechVoice
Cellos.SpeechVoice
Deranged.SpeechVoice
Fred.SpeechVoice
GoodNews.SpeechVoice
Hysterical.SpeechVoice
Junior.SpeechVoice
Kathy.SpeechVoice
Organ.SpeechVoice
Princess.SpeechVoice
Ralph.SpeechVoice
Trinoids.SpeechVoice
Vicki.SpeechVoice
Victoria.SpeechVoice
Whisper.SpeechVoice
Zarvox.SpeechVoice

この中でBadNewsとGoodNewsが使えなかったのですが、原因不明・・・

Voiceを選ぶときには-vオプションを指定する

say -v Boing San of a bitch

すべてのVoiceで発音させるシェルプログラム

すべてのVoiceを列挙して順番に発音させていきます。

Daft Punkっぽくやってみたかったけどダメだった

THE DAFT PUNK'S CONSOLE by NAJLE.comこれを見てsayコマンドでできるかな〜と簡単に考えていましたがやっぱりダメだった。
でもちょっとそれっぽくはなったかも。

全パターンを聞いてみて、「harder better faster stronger」の声に似ているのはTrinoidsでした。

これは近いんだけどキーを上げれないから厳しいな。
でも気合い入れればそれっぽくなるかも!
あとdo itのところが速過ぎるw

■関連リンク
シェルの変数に慣れる
【 文字列を置換する「sed」 】:ITpro
シェルスクリプト入門
・Macの読み上げアプリアップル - ダウンロード - ユーティリティ - iSpeech

Daft Bodies - Harder, Better, Faster, Stronger

この映像が本来のPVな気がしてきたw

ActionScript3 - HelloWorld

にとよんさんが作られたHelloWorldFlashをForkしてみた。

文字のラインにCircleを描く

forked from: Hello World!!! - wonderfl build flash online

元々のHello World!!! | wonderfl build flash onlineではFlash内をCircleで埋め尽くしていますが、ボクのほうは文字のラインにだけCircleを描くようにしています。

あとfiltersを使ってぼかして、BlendMode.ADDでキラキラさせてます。

文字のラインにアルファベットを描く

forked from: Hello World!!! - wonderfl build flash online

アルファベットにalphaを指定したいんですが、うまくいかなくてTextFieldにalphaをつける | (SCRATCHBRAIN.BLOG v2)を参考にやってみたのですが激重になってしまったので、画面の外からアルファベットを出現するようにしています。
こっちはいまいち文字が読めない感が否めない・・・

プログラムコード(Circleのほう)

PerlのMVCフレームワークCatalystをインストールしてみた

PerlのWAFを使ったことがなかったので、インストールしてみたのですがいやはや苦労しちゃいましたのでメモメモ。

インストール環境

OS
MacOS X Leopard
Perl
5.8.8

CPANからのインストール

ネットでCatalystのインストール方法を見ていると、いろんな人がいろんな方法でやっていて正直難しかったです。
どうやら以下の2つのモジュールを入れれば良さそうだと分かっても、CPANがアクセスするftpサーバーの都合でダウンロードできなかったりと意外と面倒でした。

  • Catalyst::Runtime
  • Catalyst::Devel


それで最終的に行きついたサイトが以下。
perl:catalyst [kazusa wiki]

こちらではcat-installというファイルをダウンロードし、

perl cat-install

を実行する。
これでCatalyst::Runtimeモジュールがインストールされます。

そして次に

sudo cpan Catalyst::Devel

を実行して、もう一つのモジュールをインストールします。

ただ、

Your terminal expects ISO-8859-1 (yes/no)? [yes] no

というのを聞かれなかったんだけど、途中に出てきてたのかな?
見当たりませんでしたw

CPANの接続先ftpでエラー

Not Connectのエラーがコンソールに出ていて、何回かやるとうまくいきそうなんだけど、ダメみたいでハマった。
調べてみたらCPANの接続先を追加するとうまくいくとなっていたので以下を参考に追加してみました。
LunaTear: CPANのサーバー追加

cpan
cpan> o conf urllist push ftp://ftp.u-aizu.ac.jp/pub/CPAN
cpan> o conf urllist push ftp://ftp.dti.ad.jp/pub/lang/CPAN/

そして一応追加されているか確認。

cpan> o conf urllist

大丈夫だったら

cpan> o conf commit

これで変更が反映されます。
commitしないといくらやっても接続先サーバーが追加されないので注意が必要です。

雛形を作ってみる

Ruby on Railsのようにザクッとテンプレートを作ってくれるので、ここがCatalystの魅力なんでしょうね。
コンソールで、

catalyst.pl HelloWorld

これでモデル、コントロール、ビューあたりが自動生成されるようです。

そしたらHelloWorldフォルダの中にあるスクリプトを実行してスタンドアロンな簡易サーバーを起動してみます。

cd HelloWorld
./script/helloworld_server.pl

これを実行するとコンソールにURLが表示されるので、後はブラウザでアクセスするだけです。

HelloWorld on Catalyst 5.80002

まとめ

Javaに慣れていると必要なライブラリはlibの中に入れとけば動くという感覚なんですが、こうゆう風にCPANから必要モジュールをインストールし、それらが「/Library/Perl/5.8.8」に勝手に展開されて後は呼び出すだけというのがまだちょっと慣れない。
どちらかと言えばプロジェクト単位にライブラリを配置したいという感じがします。

Movable Typeなんかがその方法を使っていて、必要なCPANモジュールはextlibというフォルダに格納されています。
なのでプログラムコードの中でそこを見に行くように、

なんてことをしないといけないのですが、どちらかというとボクはこっちより。
このブログのレンタルサーバーはロリポップを使っているのですが、telnetもsshも使えないのでCPANからインストールという方法が使えなそうです。
だからデプロイもftpになるのかな?めっ、面倒だ・・・w

最もシンプルにJavaのAOPを書いてみる→そしてJavaScriptへ

SpringSeasar2などのFrameworkを使っているとDIやAOPを簡単に実現できますが、このAOPを自前で手軽に書くにはどうやるのかな〜と思って調べてみた。
AOPとは[ThinkIT] 第5回:AOPとは何か (1/4)あたりを読むと分かりますが、ある処理を実行する前や後に追加で処理を入れることをいい、しかも実装クラスには手をつけずに外から処理を追加するように見せるのが特徴です。

ではシンプルにAOPを実現するコードを書いてみます。
今回はServiceというInterfaceを実装したServiceImplに文字を出力する処理だけを記述し、その前後にロギングの処理をAOPで織り込んでおきます。

Main.java

まずはメインとなる実行クラスを作ります。
このクラスで重要なのはProxy.newProxyInstanceというメソッドを使ってプロキシクラスを取得していることです。
たとえばServiceImplを普通にnewしてしまうと、純粋に文字を出力する処理しか存在しませんがこれではAOPを入れる隙間がありません。
なのでプロキシクラスを経由してServiceImplの処理を呼んでもらうようにします。

それがProxyというクラスの役目になります。

Proxy.newProxyInstanceメソッドの引数は

ClassLoader
プロキシクラスを定義するクラスローダ
Class<?>[]
プロキシクラスが実装するインタフェースのリスト
InvocationHandler
メソッド呼び出しのディスパッチ先の呼び出しハンドラ

になります。
第3引数に渡すInvocationHandlerに渡すクラスが実際のAOPとして折り込みたい処理を実装したクラスになります。
詳細は後で紹介します。

■参考リンク
Proxy (Java 2 Platform SE 5.0)

Service.java

普通にインターフェースです。

ServiceImpl.java

文字出力処理を実装しているクラスになります。
文字を出力し、returnとして出力した文字を返しています。

Intercepter.java

プロキシを作成するためにまずはInvocationHandlerインターフェースをimplementする必要があります。
そしてService.print()が呼び出されるとこのクラスのinvokeがディスパッチされます。

invokeメソッドの引数は

Object proxy
プロキシクラスの参照
Method
呼び出されたメソッドのMethodオブジェクト
Object[]
呼び出されたメソッドの引数配列

になっています。
ひとつ気をつけたいのはmethod.invokeを呼び出すさいの第1引数はproxy変数ではないことです。
proxy変数にはプロキシクラスの参照が入っているので、もしproxy変数をmethod.invokeに渡してしまうと無限にループしてしまいます。
なのでこのクラスではコンストラクタに実装クラスを渡すようにしています。
そして実装クラスをオブジェクトとしてmethodを呼び出します。

■参考リンク
InvocationHandler


これらを実装してMain.javaを実行するとprintの前と後にログ処理が追加され文字がコンソールに出力されます。
ちょっぴり面倒ですが、Intercepterクラスをしっかり作ればもっといろんあ織り込み処理が作れそうですね。

JavaScriptでAOPを実現してみる

では次にJavaScriptで↑で説明したようなAOPを作ってみたいと思います。
名前を一緒にしたほうが分かりやすいのでProxy.newProxyInstanceという関数を作り、この関数からプロキシオブジェクトを取得します。
実際にはオブジェクトを作り直しているだけですが、JavaのProxyクラスも同じようなことをやっているのでそこまで違いはないと思います。

コードは以下のとおり。

まとめ

JavaScriptでAOPを使うことは今のところないとは思いますが、いずれクライアントサイド・ストレージを使ってブラウザ側のDBを使うときにトランザクションをAOPを使って織り込みたいといった要望がでてきたときに便利かもしれません。
trycatchで囲ったりしてコネクション繋いだりトランザクション貼ったりするのはコード量も増えますし、結構面倒だったりもしますしね。

jQueryでツールチップを表示するシンプルなコード

そこまでシンプルでもないかもしれませんが、一応書いてみた。

構成としては、

  1. チップ用のdivタグを生成する
  2. チップを表示する対象となるSelectorにマウスイベントをセットする

これだけ。


■プログラムコード
一応jQueryPluginとして書いてみました。

このjsを読み込んだら、後は以下のように呼び出すだけ。

何度も呼ぶのがちょっと・・・
もうちょいキレイにして機能追加してPlugin化するのもありかな。

追記:
一応デモを用意してみた。
jAltTip.js - jQuery Plugin

Papervision3D - BitmapLayerEffectを試してみた

Mozilla Firefox

ActionScriptで3D空間 - Papervision3Dをためしてみたに引き続きPapervision3Dで遊んでみた。

Papervision3Dが持つBitmapLayerEffectクラスでどうやらエフェクト効果を付けられるようなので、試してみました。
それと奥のほうからズームするようにプログラムを少し修正。

ちょっぴり3Dっぽくなってきました。

Continue reading

ActionScriptで3D空間 - Papervision3Dをためしてみた

ActionScriptで3D空間 - Papervision3Dをためしてみた

Papervision3DはFlashを使って3D空間を簡単に作成できるようにしたActionScriptライブラリです。
Versionが1.Xから2.Xに変わって、かなり仕様が変わったようでネットに転がっているサンプルが結構動かなくて四苦八苦してしまったのでメモメモ。

ぶっちゃけ簡単にと言いましたがそれでもかなり敷居が高いと思います。
でも100行ちょいで3Dを描くことができるので、使い始めるとあっという間に時間がすぎてくほど面白いライブラリ。

ではさっそく使ってみましょう。

Continue reading

いろんな言語のSetter・Getterを比較してみた

プロパティ(属性)を持つクラスを使う場面は開発を行って行くと多々ありますが、各言語によって書き方はまちまちです。

とは言っても目指すところは同じだと思いますので、以下に何個か載せてみました。

JavaScriptのSetter・Getter

IE6、7で実装されていないため、今まで開発では全く使ったことがないですが、使い始めると便利そうですね。

現時点では以下の2パターンでgettter、setterを定義できる。

・Firefox独自実装、その後Safari・Operaも実装

  • __defineSetter__
  • __defineGetter__


・ECMAScript3.1実装

  • get getter()
  • set setter(value)


以下のコードはFirefox、Safari、Operaで動作確認済。

またIE8に実装されたObject.definePropertyメソッドというのがあるみたいなんですが、手元にIE8がないため確認できてないです。
詳細は以下に記述されてます。
IE8 の DOM のプロトタイプと Getter/Setter API はどうなるか - IT戦記
次の JavaScript の仕様はこうなる! ECMAScript 3.0 から 3.1 への変更点まとめ - IT戦記

ActionScript3のSetter・Getter

なんとなくこっちのほうが使う機会が多そう。


詳しい内容は以下からどうぞ。
【AS3入門】getterとsetter - 独学ActionScript

PerlのSetter・Getter

Perlでアクセサメソッドを作ろうとするとちょっぴりコード量が膨らみます。
ようは引数があればSetterと見なし、引数がなければGetterと見なすという感じです。

これをもっと簡略化してくれるCPANモジュールのMooseが気になるところです。

RubyのSetter・Getter

Rubyではそもそもオブジェクトの外部からインスタンス変数を直接参照することができないので、アクセサメソッドが必須になってきます。

以下の例は自分でアクセサを作った場合


でもこれを属性分作るのは面倒なので、以下のように簡単にアクセサメソッドを作ることができます。
ここらへんがRubyっぽいですね。

JavaのSetter・Getter

Javaのアクセサはみなさんご存知ごくごく一般的な感じ。
まぁこれでもEclipseの自動生成を使えば、Getter・Setterは自動で作ってくれるので便利と言えば便利なんですけどね。

まとめ

JavaScriptはやっぱり今の時点でもクロスブラウザの問題が出てきてて、実際に使われるのかどうかそのあたりが難しいところですが、
でもこうして見てみると昔のJavaScriptでは考えられないほど使いやすくなっているような気がします。

Rubyのように1行書けばよいのもあれば、setNameのように自前でメソッドを作らないといけないJavaなんかもあったり言語間ではバラバラなのはしょうがないですね。
いろんな言語を跨ぐと、この言語はどうだったっけかな?みたいに迷ってしまいそうですw

どうしてアクセサメソッドなんて面倒なものを使わないといけないのかは以下のリンクを参考にしてください。
オブジェクト指向プログラムでgetter/setterメソッドを使わなければならない10の理由

JavaScript版Box2dを手軽に使えるようにprotoBox2d書いてみた

Box2DJS - Physics Engine for JavaScript

ActionScriptで有名な(確か元はC++だったような)Box2dのJavaScript版がいつの間にか存在していたので手軽に扱えるようにprotoBox2dを書いてみました。
Box2d自体がprototype.jsを必須にしているので、やむなくボクもprototype.jsで書きました。
ここ最近jQueryばっかだったから正直prototype.jsがきつく感じられた。

一応IE6でも落下のみはできるのですが、すんごい重いです。
IE7はドラッグアンドドロップまでできるようにしてあります。ただこちらも重いです。

Webkit系のブラウザのSafariGoogle Chromeで試してください。ホイホイ投げれます。

デモ、詳細は以下からどうぞ。
protoBox2d.js - Box2d JavaScript Library

[via]
sasapong's room

jQueryでマウスから逃げるRunAwayFromMouse書いてみた Part2

RunAwayFromMouse.js

jQueryでマウスから逃げるRunAwayFromMouse書いてみたで書いたコードを改良して、マウスが動かなくなっても元の位置に戻ろうとするようにした。

それと逃げる範囲を大きくしたので、バラける感じがうまく表現できたと思う。

今まではマウスが動いたたびにmousemoveイベントでエレメントの個数分ループさせていたのですが、これだとめちゃくちゃ遅くてまずはここを以下のように改良した。

mousemoveイベントのコード

このイベント時はマウス座標を変数に格納するだけを行い、エレメントを逃げさせる処理は別のタイマーで書いた。
それが以下。

タイマーでエレメントを動かすコード

一応60ms単位でエレメントを動かしているが、もう少し感覚を短くしても問題はなさそうだ。
ただしやっぱりFirefoxだともっさりしてしまうので、大体60ms程度が望ましい。

動作は以下のリンクからどうぞ。

RunAwayFromMouse.js

まとめ

マウスの座標はmousemoveなどのイベント時じゃないと取得できないので、このイベントでは最小のコードを実行して、別スレッドでエレメントを動かすという発想はマウスから逃げるように文字が移動するJavaScriptから拝借した。

こうゆう最適化って一見面倒そうに感じますが、やってみると体感がいい感じになるので突き詰めていきたい感じです。

jQueryオブジェクトから配列に変換してくれるmakeArray

jQueryオブジェクトに複数のエレメントが格納されてて、これらをまとめた配列なんかが欲しいときに便利な関数。

lengthプロパティを持っていれば配列に変換してくれるようなので、独自なオブジェクトにも使えそう。

使い方は以下のような感じ。childrenで複数の要素を持つjQueryオブジェクトを配列に変換しています。

これ初めて使いましたw

画像がグルグル回るjQuery Plugin - jMerrygoround作りました

jMerrygoround - jQuery Plugin

仕事の一環で作ってみたのですが、使わなかったのでリニューアルして公開してみます。
普通に回るのはすでにあったりするのですが、ちょっとオモロ〜に回してみたいという方向けに作ってあります。
デモのところでいろいろ遊んでください。

この命名ははじめjSliderとかそのあたりの名前にしようかと思ったんですが、いまいちパッとこなくて、嫁さんに画像が回るのを見せながら「これ例えるなら何かな?」って聞いたら「メリーゴーランドだね!」と回答がきたので決定しましたw

追記:fukkenさんのいうカルーセルという名前もすでに結構使われてて、これは速攻でやめましたw


デモ、詳細は以下からどうぞ。
jMerrygoround - jQuery Plugin


あとキングボンビーがサイトを侵略する?jQuery Plugin - kingbonbi.js作りましたダンスっぽいことしたいと言っていたのでjMerrygoround Demo - actionMouseoverKingbonbiなんかも作ってみました。

Firefoxのリンクをクリックしたときの点線を消す方法

Twitter / 30DB30FC30E0

JavaScriptでaタグをクリックしてアニメーションさせるときとかに気になりがちな点線をCSSで消す方法です。

[via]
CSS Hacks and Issues

jQueryでマウスから逃げるRunAwayFromMouse書いてみた

untitled

マウスから逃げるFlashがかっこいいで紹介したFlashをJavaScriptで書いてみた。
マウスの移動に伴って回りの要素が逃げるように動きます。

canvasタグとdivタグの2パータンで作ってみたんですが、どちらもFlashとくらべるとかなりもっさりしちゃいますねw
Firefoxでは50個、Webkitでは100個を描画しています。
多分divタグのほうがcanvasタグより軽いです。

なのでSafariかChromeあたりでも見てもらえるとそれっぽくなると思います。

サンプル

コード

つくづく思いますが、jQuery使うとコードも少なくてすむので楽ですね〜。

マウスから逃げるFlashがかっこいい

マウスから逃げる - wonderfl build flash online

このぼやけた感じがすごいネオンぽくてすてきです。

AS?? - wonderfl build flash online

こっちのクリアな丸がなんかブドウっぽくてかわいい。


今日はこの2個のFlashを見て遊んでた。
自分でいろいろカスタマイズできるのが、このwonderflというサイトの特徴なんですが、
面白法人カヤックもなかなか良いサイト作りますな。

jQueryでサイト内リンクを使ってSmoothなScrollをする方法

追記(2009/03/30):
hashがない場合にreturnするように修正。
これがないと<a href="#">とかの場合にスクリプトエラーになるため。

サイト内リンクでアンカータグにhref="#hoge"なんて指定している場合に使えそうなscroller

これで自動でアンカータグをクリックするとアニメーションしながら目的値のところまでスクロールしてくれる。

^は初めの文字が#だった場合という意味なので、*にしてもよいかも。
もしhref="http://hoge.com/#hoge"とかの場合にはこの方法が有効。

こんなもんでいいのかな?
なんかさらにもっと簡単な方法がありそうだけど。

画像に水面の反射のような効果を付けられるReflector.js作りました

Reflector

既存であったりするんですが、自分が使いやすいように作ってみました。
以下の2パターンで画像のリフレクションを設定することができます。

reflection="true"が指定されたエレメントを一括でリフレクションさせる場合は以下のように記述してください。

エレメントを引数に渡してひとつの画像をリフレクションさせたい場合は以下のように記述してください。

詳細は以下のリンクからどうぞ。
Reflector.js - JavaScript Library

WiiリモコンからTwitterにPostしてみた

前に胎児がTwitterにPostする? - kickbeeBluetooth経由でお腹にいる赤ちゃんのキックをPostするというのを紹介したのですが、ためしにWiiのリモコンからやってみても面白いかも!ってことで試してみました。

最終的にはWiiリモコンの押したボタンをTwitterにPostするようにしてみます。

開発環境

まずは今回試した環境を以下に記載します。

OS
Mac OS X Leopard
JDK
1.5以降
BlueTooth
必須
コントローラー
任天堂Wiiリモコン

JDKが1.5以降となっているのは、今回使ったライブラリが1.5以降を必須としているためです。

どうやって通信するの?

Wiiリモコンと会話するにはBlueToothが必須になります。
そしてBlueToothから来たパケットを処理してどのボタンが押されたのか、または今どの座標にいるかなどを取得する必要がありますが、そういった基本機能はすでにライブラリとして提供されています。

なのでまずは簡単にライブラリの説明をして、その後実際にコードを書いてみたいと思います。

BlueCove - JSR082 API

JSR082 APIというのはBlueToothにアクセスする基本的なインターフェースを提供してくれます。
そしてMacやPC用に作られたオープンソースなライブラリは、「BlueCove」になります。

以下からbluecove-2.1.0.jarをダウンロードしました。
Downloads - bluecove - Google Code

WIIREMOTEJ

WiiRemoteJはMac OS XとWiiリモコンを繋ぐインターフェースを提供してくれるライブラリです。
先ほどのJSR 82を使ってWiiリモコンを探し出し、細かいプロトコルの変換なども自動で行ってくれるすぐれたライブラリです。

以下からWiiRemoteJ v1.6.zip.gzをダウンロードしました。
Index of /WiiRemoteJ

WiiリモコンとMacを繋いでみる

ボクは今回Eclipseを使って開発を行いましたのでその手順を以下に記載します。
まずは上記2つのライブラリをプロジェクトにドラッグし、ビルドパスを通しておきます。

WIIREMOTEJをダウンロードすると付属してくるファイルの中から

  • WRLImpl.java
  • Audio.au

をプロジェクトに追加します。
WRLImpl.javaはWiiリモコンとの基本的な操作が書かれたサンプルで、この中に今回使うエッセンスがぎっしり詰まっています。
またAudio.auは40秒間のサウンドクリップになりますが、JavaからWiiリモコンに音を出すときに使います。
もし音は出さなくてもよいという人はプロジェクトに含めなくても大丈夫です。

そしてWRLImpl.javaを実行してみます。

BlueCove version 2.1.0 on mac

とコンソールに表示されると思います。

このタイミングでWiiリモコンの1ボタンと2ボタンを同時押しします。
するとWiiリモコンの4つのライトが点滅しますので、コンソールを見て少し待ちます。

少しするとコンソールにいろいろ出力されますが、

java.lang.IllegalStateException: Devices are already being found! Only one "find" operation may run at once.

と表示されいっこうにスタンバイ状態にならなかったので、ハマりましたw
調べてみると海外の人で同じ現象になってる人がいました。
WiiLi.org java.lang.IllegalArgumentException: PCM values restricted by
に書いてあったのですが、

をMainメソッドの一番初めて入れればうまく動きました。

これでまた先ほどと同様にWRLImpl.javaを実行し、Wiiリモコンの1ボタンと2ボタンを押してみます。
Javaが起動してから3秒後くらいにボタンを押すとエラーになりにくくなりますが、もしうまく接続できない場合は何度か試してみてください。(なかなか一発で繋がりません・・・)

エラー内容が、

Failed to connect remote. Trying again.

の場合は一回Java側を停止さえてもう一度起動したほうが早く繋がるようになると思います。

とりあえず遊んでみる!

繋がったらWiiリモコンを振ってみたり、各ボタンを押してみるとコンソールにその情報が表示されると思います。
この時点ですげ〜感動!!

Accelerometer graph: Wii Remote

振ると画面の表示もこの画像のようになると思います。
とりあえずこれでうまく繋がりました。

TwitterにPostしてみる

先ほどのWRLImpl.javaをサンプルにして、以下のコードを書いてみました。
WiiRemoteJ.findRemote()が実際にWiiリモコンを探し出すコードです。このメソッドを呼ぶだけでWiiリモコンと繋がるなんてめちゃくちゃ便利!

addWiiRemoteListenerにリスナーをセットし、buttonInputReceivedメソッドは、ボタンを押したら呼ばれる部分になります。
なので、この部分にどのボタンを押したかをTwitterにPostする処理を入れています。
TwitterにPostする処理はTwitter4Jを使わせていただきました。

gist: 82868 - GitHub

結果:
P3:PeraPeraPrv

ほとんど自分でコードを書かなくてもこれぐらいのことができちゃうのがすごいですね。

番外編 - Wiiリモコンから音を出してみる

先ほどのAudio.au音楽ファイルを使ってWiiリモコンから音を出すサンプルです。
まぁWiiリモコンのスピーカーなので、あんまり音はでないですが、とりあえず何となく音は聞こえたのでよしとします。

gist: 82871 - GitHub

YouTubeでWiiリモコンからナイトライダーを流す動画がありました。
こんなにちゃんと音出るのかな?

Knight Rider Wii Remote

まとめ

ライブラリが充実していてほとんど自分でコードを書かなくてもこれぐらいのことができちゃうのはやっぱりすごいことですね。
動かなくて四苦八苦はしましたが、ハマるというのもこうゆう遊び感覚のコーディングの楽しいところです。

あとSourceForge.net: DarwiinRemote: Filesというアプリを使うとWiiリモコンでマウス操作ができるようになるのですが、ボクの環境なのかほとんど使いもんにならなかったですw

■参考リンク
WiiLi.org Wii Linux - JP:WiiremoteJ/Installation
WiiLi.org Wii Linux - JP:WiiremoteJ/ReadMe
JavaとWiiリモコンをBluetoothでつなげてみよう - ブログ: 岡崎 - Okazaki's blog
BlueCoveConfigProperties ( bluecove 2.1.1 -スナップショットAPI )を

JavaScriptで関数内のthisを文字列にする方法

jQuery() の挙動を解読する(29) jQuery.css() クラスメソッド upon ver1.3.2──jQuery解読(43)を読んでいて、jQueryのeachではthisが第1引数(文字列とか)になると書かれていたので実際に試してみた。

ソースコード

どうやら文字列を渡すとnew String()を行った状態で呼び出し先関数のthisにセットされるみたいですね。
そのthisと文字列結合をするとobject型からstring型へ自動でキャストしてくれます。

う~ん、今まで文字列なんて渡したことがなかったのですごい新鮮w

jQueryの場合

-webkit-transformを使ったCSSアニメーションを試してみた

Safari3.1以上で搭載されたCSSプロパティ-webkit-transformいまさらながら試してみた。
ChromeかSafari3.1以上で触ってみてください。

-webkit-transitionでアニメーションさせるCSSプロパティを指定して、例えばhoverでそのCSSプロパティの値を変更すればJavaScriptで実行しているようなアニメーションをしてくれる。

また-webkit-transform-originに50%を渡しているが、これはデフォルト50%なので特に意味はない。

translate、scale、rotateの合わせ技

透過

クリックで回転

ボーダー伸び縮み

※注意:0pxにするときにsolidがないとアニメーションしてくれない。


■関連リンク
Surfin’ Safari - Blog Archive ≫ CSS Animation
Weblog  Safari 3.1でやってみたかった3つの事
The Art of Web ~ CSS: Animation Using CSS Transforms

Twitterがクリックジャッキングを防止している方法

いつの間にかクリックジャッキングという脅威が発見されて、これはこれで恐ろしいな~と思いメモしとく。

クリックジャッキングとは、透過指定されたiframeなどの要素に標的サイトのコンテンツを読み込み、これを攻撃者サイトの要素よりも上に配置することで、Webブラウザの画面上には攻撃者サイトの要素だけを表示させ、その上でユーザーが行うクリック操作を標的サイトに対して行わせるもの。


via:
主要ブラウザすべてに影響する「クリックジャッキング」攻撃とは

なかなか巧妙だが確かにできる手法ではある。
また透過されているのでサイト訪問者は攻撃者サイトを見ていると思い込んでいるが、実は標的サイトが前面にきているのでもしボタンやテキストボックスの位置をうまいこと偽装すると容易にログイン情報などを盗み取れてしまう・・・怖い

2月にもTwitterがこの攻撃を受けて意図しない投稿をさせられてしまうという事例があったそうな。
んで、ローカルでiframeを読み込むHTMLを作成し、「http://twitter.com/home」を読み込んでみた。

一瞬普通にTwitterのホーム画面が出るが画面のレンダリングが下のほうに達すると何も表示されなくなったので何かしら対応したのだろう。

どのように対応したかは以下のソース。

攻撃者サイトがiframeで標的サイトを読み込んでいる

まずここでは標的サイトをiframeで読み込む。

標的サイト側ではwindow.top !== window.selfで不正に読み込まれたか判断している

window.top !== window.selfで自分自身がtopでない場合にinnerHTMLを空文字で上書きしている。
確かにこれならクリックジャッキングを防げそうだが、ブラウザのscriptが無効になっていると意味がない。

対応策

IE8 RC1にクリックジャッキングの問題を解決した機能が実装されているようだが、これはIE8の普及率に依存しそうだ。

FirefoxユーザーならクリックジャッキングにFirefox+NoScriptで対抗できるのか?で紹介されているNoScriptを入れて「<IFRAME>の禁止」にチェックを入れれば防げそうだ。
だたGoogle Adsenseはiframeを使って広告を出しているから、広告費で生計を立てている企業からするとこれはこれで痛そうだw

現時点ではこれぐらいしか防ぐ手立てがないようなので、信頼していないサイトでは閲覧のみにして入力するなどは控えめにしたほうがよさそうということですね。

CSS3のbox-sizingでpadding・borderをwidth、heightに含めてみる

CSS3 Basic User Interface Module

一般的にエレメントのwidthやheightはpadding・borderなどは含まないがこれを含めるかどうか指定できるのがこのbox-sizingだそうだ。

たとえばCSS3 box-sizing attribute - Helephant.comに書いてある画像を見てもらえれば分かるが、2個のfloatしているdivタグがあり一方は「width:30%」、もう一方は「width:70%」としている。
この場合は1pxでもpadding・borderなどがあると下に滑り落ちてしまうのだが、これを防ぐためにbox-sizingを使っている。

box-sizingで指定できるのは以下の値になる。

content-box
padding・borderを含めない
border-box
padding・borderを含める

ちなみにまだOpera以外のブラウザではbox-sizingと記述しても機能しない。
独自実装な-moz、-webkit、-ms-boxをプレフィックス付与して記述する必要がある。

box-sizingを使った例

box-sizingを指定しないパターンから指定したパターンで試してもらうと分かるのですが、id="div2"が下に落っこちない!
当たり前だがmarginを指定すると落っこちます。

使えるブラウザ

  • Firefox2以上
  • Safari3.1以上
  • Chrome0.2以上
  • Opera9.6以上
  • IE8以上

[via]
When can I use...

IETesterで試してみたが、一応Beta2では使えたお。

HTMLタグにカスタムな属性を追加しJSから取得する方法

HTMLタグにカスタムな属性を追加しJSから取得する方法

なんかいまさらな気もしますが備忘録として。

たとえばdojoなんかを使っていると以下のようにエレメントの属性に見たこともないのが書いてあったりする。

dojoのカスタム属性の場合

scriptタグのdjConfig、divタグのdojoTypeがそうですね。

自前のカスタム属性の場合

これを単純に自前でやってみる。

divタグにhogeという属性を書いて見ていざelem.hogeで値を表示しようと試みるがFirefoxでundefinedが返ってきてしまう。
でもIEではうまく取れた・・・

なんでだろう・・・

とりあえずFirebugで追ってみた。

まずはelemオブジェクトを見てみる。

一生懸命hogeプロパティを探してみるが見つからない。だがidプロパティは存在している。

次に属性としてちゃんと登録されているか確かめてみる。

として、attributesの中身を拝見。

item(0)
Attr nodeName=hoge nodeValue=hoge nodeType=2
item(1)
Attr nodeName=id nodeValue=hoge nodeType=2 childNodes=[1]
length
2

一部割愛したが属性の個数が2個になってる!
そして0番目にはnodeName=hogeと、hoge属性が格納されていた。

まとめ

普段あんまり気にしていなかったが、自分で追加した属性値はelem.hogeと書いても取得することができない。(Firefoxだと)
なので以下のようにして取得すること!

ちなみにjQueryを使っているなら以下のように書くからあんまり気にしないでも問題ないですね。

NodeList・HTMLCollectionを返すメソッド一覧

かなり個人的なメモですが、NodeList型や、HTMLCollection型を返すメソッドをまとめてみました。
また資料がDOM Level 1と古かったりもするので、必ずしも今のDOMレベルに合っていないかもしれません。

NodeListのメンバ

length
このプロパティは int 型である。
item(index)
このメソッドは Node を返す。index パラメータは unsigned long 型である。

HTMLCollectionのメンバ

length
このプロパティは int 型である。
item(index)
このメソッドは Node を返す。index パラメータは unsigned long 型である。
namedItem(name)
このメソッドは Node を返す。name パラメータは DOMString 型である。

NodeList型を返すメソッド

Document

getElementsByTagName(tagname)
このメソッドは NodeList を返す。tagname パラメータは DOMString 型である。

Node

childNodes
このプロパティは NodeList 型である。

Element

getElementsByTagName(name)
このメソッドは NodeList を返す。name パラメータは DOMString 型である。

HTMLDocument

getElementsByName(elementName)
このメソッドは NodeList を返す。elementName パラメータは DOMString 型である。

HTMLCollection型を返すメソッド

HTMLDocument

images
このプロパティは HTMLCollection 型である。
applets
このプロパティは HTMLCollection 型である。
links
このプロパティは HTMLCollection 型である。
forms
このプロパティは HTMLCollection 型である。
anchors
このプロパティは HTMLCollection 型である。

HTMLFormElement

elements
このプロパティは HTMLCollection 型である。

HTMLSelectElement

options
このプロパティは HTMLCollection 型である。

HTMLMapElement

areas
このプロパティは HTMLCollection 型である。

HTMLTableElement

rows
このプロパティは HTMLCollection 型である。
tBodies
このプロパティは HTMLCollection 型である。

HTMLTableSectionElement

rows
このプロパティは HTMLCollection 型である。

HTMLTableRowElement

cells
このプロパティは HTMLCollection 型である。

番外編

基本的に↑に書いたメソッドやプロパティはLiveなNodeList、HTMLCollectionになる。
ただし、以下のquerySelectorAllメソッドはStaticなNodeListが返るという仕様?(バグ?)だそうだ。

たとえば以下のようなコードを実行してもらえば分かるだろう。

Selectors API

querySelector
このプロパティは Element 型を返すので今回のとは違うな。
querySelectorAll
このメソッドは NodeList を返す。name パラメータは DOMString 型である。

querySelectorAllがliveじゃないNodeList返すのはなんで? - vantguarde - web:gでもあるようにliveじゃないStaticNodeListが返るめずらしいメソッド。

参考にした資料

付録 E: ECMAスクリプト言語バインディング

Document Object Model (Core) Level 1
Document Object Model Core Level 2
Document Object Model Core

第23回 NodeListインターフェイスを利用する
Web Kit DOM Programming Topics: JavaScriptからのドキュメントオブジェクトモデルの使用

FirebugがXMLHttpRequestを監視している方法を読んでみる

JavaScriptを使って何か物を作っている人はまず間違いなくFirebugを使っているというほどFirebugは世の中のJavaScripterに浸透しています。

alert文をひたすら書いてデバッグしていた時期が懐かしいです。(今でもalertを使うことはありますが)

そして一番楽になったといえばAjax関連の開発が昔と比べて格段に楽になりました。
これはAjaxリクエストが送信されたタイミングと応答が返ってきたタイミングでFirebugがコンソールに内容を出力してくれるからだと思います。
これ以外にもどれくらい通信速度がかかったかなども見ることができるのでとってもありがたいです。

そんなAjaxの監視をFirebugが一体どうやってやっているのかをここで紹介してみようと思います。

Firebugインストール

Firebugがまだ入っていない人はFirefoxを立ち上げてFirebugを入れてみましょう!

Firebug :: Firefox Add-ons

ソースコードの場所

ボクの環境では以下の場所にFirebugが置いてあります。

C:\Documents and Settings\hogeuser\Application Data\Mozilla\Firefox\Profiles\yrljtiye.dev\extensions\firebug@software.joehewitt.com

もうみなさんも慣れて来たと思いますが、実際のコードはこのディレクトリのcontentフォルダの中にあります。
ここにJavaScriptやらxulやらCSSなどがゴロゴロありますが、今回見るファイルはそんなに多くはないので大丈夫です!

ソースコードリーディング

ボクはこの手のソースコードを追う場合は、まずは関連しそうなキーワードでgrepしちゃいます。
たとえば今回はAjax部分の監視をしている箇所なので、おそらく「XMLHttpRequestがなんたらかんたら」みたいな部分がありそうだな~なんて。

なので「XMLHttpRequest」でgrepし、そこからソースコードリーディングを始めてみたいと思います。
grepする範囲はcontentディレクト内の全ファイルからということにしてみます。

またコードの量がそこそこ多いので、メソッドの中とかかなり端折った形で紹介していきますのでご了承ください。

net.js

XMLHttpRequestをキーワードにgrepした結果、net.jsがとってもあやしそうです。
2047行目にinstanceofでXMLHttpRequestかどうかを判断している箇所があるので、なんとなくここっぽいですね。

2047行目

では次にここのgetRequestWebProgressメソッドを呼び出している箇所に飛びましょう

どうやら同じファイルの2658行目のonModifyRequestメソッドから呼ばれているみたいです。

2658行目

onExamineResponseメソッドからも呼ばれているようですが、onModifyRequestメソッドのほうがネーミング的にとっつきやすいのでとりあえずこっちでw

ではさらにonModifyRequestメソッドを呼び出している箇所に飛びましょう

すぐ上にあるobserveというメソッドが読んでいるようです。
ここまでの時点でなんとなく見えてきましたね。

リクエストが送信されるタイミングでonModifyRequestメソッドが呼び出され、その中のgetRequestWebProgressメソッド内でXMLHttpRequestかどうかを判断しているという感じです。

ではobserveがいつ呼ばれるのかが知りたいところ。
とりあえずobserveでgrepをしてみたもののいまいち呼び出している箇所がなさそうです。

リフレクションだと見つけにくいな~なんて思っていたら、registerObserverというメソッドがあるのに気がつきました。
う~ん、登録しているのか~。あやし~い~。

ということで2609行目のregisterObserverを見てみます。

2609行目

なんとなく2種類のイベントにHttpObserverというオブジェクトを渡しているのが確認できます。
実はこのhttp-on-modify-requestというイベントが今回のキモになります。
http-on-modify-requestとは

http リクエストが作られたときに呼ばれます。通信路 (channel)
はヘッダーなどの変更などが可能です。


via: Observer Notifications - MDC

とhttpリクエストが送信されたときに呼ばれるそうです。
さらにaddObserverメソッドの第1引数には、nsIObserverインターフェースを実装したオブジェクトを渡すようにと書かれています。

[scriptable, uuid(DB242E01-E4D9-11d2-9DDE-000064657374)]
interface nsIObserver : nsISupports {
void observe( in nsISupports aSubject,
in string aTopic,
in wstring aData );
};

nsIObserver - MDC(肝心な部分が英語ですがw)
nsIObserverService - MDC

ということはリクエストが送信されたタイミングで、イベントhttp-on-modify-requestにセットされたHttpObserverオブジェクトのobserveメソッドが呼び出されるという仕組みになりますね。

やっとobserveが呼び出されるポイントがつかめました。
先に進みましょう!

次はイベントを登録していたregisterObserverメソッドを呼び出している箇所です。

grepした結果192行目で呼び出しているようです。

192行目

じゃあこのinitializeUIメソッドを呼び出している箇所はというと・・・
grepしてみても他のオブジェクトのinitializeUIメソッドは呼ばれているようなんですが、肝心なFirebug.NetMonitorのinitializeUIメソッドが呼ばれている箇所が見当たりません。

・・・

実は2804行目でFirebug.registerActivableModuleメソッドにFirebug.NetMonitorを渡しているようです。

2804行目

なんとなく見えてくるのがinitializeUIはどうやら登録しておけば勝手に呼ばれるメソッドなの?みたいな。

firebug.js

実は登録したメソッドを呼び出している箇所がfirebug.jsの224行目になります。

224行目

このメソッドの

がそれにあたります。

Firebug.registerActivableModuleメソッドで登録しておいたinitializeUIをdispatch関数がリフレクションで呼び出してくれている感じになります。

ではFirebug.initializeUIメソッドはダレが呼んでいるのかと。

chrome.js

chrome.jsの157行目に

157行目

となっているのでおそらくこの部分ですね。

ではさらにさかのぼってFirebugChrome.initializeUIを呼んでいる部分へ!

1043行目のbrowser1Loadedという関数の中にありました。

1043行目

さらに次~!

browser1Loaded関数は102行目で

102行目

ほほぅ、loadイベントですね。分かります!
これは拡張がロードされたタイミングのイベントになりますね。

さらに次~!

initializeメソッドを呼び出しているのはすぐ上のpanelBarReadyメソッドになります。

58行目

bindings.xml

最後のFirebugChrome.panelBarReadyメソッドは実はJavaScriptファイルからの呼び出してではなくbindings.xmlというbindingを定義しているファイルからになります。

id="panelBar"というbinding要素が生成されたタイミングでconstructorタグ内の処理が呼ばれます。
このときにFirebugChrome.panelBarReadyメソッドを呼び出しているということですね。


これでやっと、


FirebugにAjax通信したときに表示される仕組みが分かりました!


最後のほうはグダグダでしたが、なんとなくFirebugがXMLHttpRequest送信時にconsoleにログをはく仕組みを理解していただいたと思います。
普段使っているだけあって、こうゆうところにも注意して見てみると面白いですね。

番外編:いつも使っているエディター

ボクがつかっているエディターはPeggyというエディターでシェアウェアですが、1ヶ月のお試し期間があります。

あんまり使っている人がいないようですが、ボクにとっては最強のエディターです。
オススメな機能はプロジェクトを持てることですね。

プロジェクトを作成して、例えばFirebugのソースを一式登録しておけばいつでもプロジェクトファイルを開くだけで見ることができます。
ボクの中では軽いIDEみたいな扱いになってますw
あとスニペットもデフォルトでかなり入っていて、自分で登録も簡単にできるのでJS書くときは便利です。

「func」まで入力したら後はCtrl+/でインテリセンスみたいな。

MacのときはTextMateですね。
PeggyはWindow版のTextMateみたいな感じで使ってます。(スニペットがヤヴァ過ぎる!)

Ruby on RailsのコーディングスタイルにTextMateは最適ですが、jQueryやPrototype.jsのコーディング時にも役にたちます。

拡張的な参考記事

Firefox拡張機能(Extention)の簡単な作り方メモFirefox拡張機能(Extention)の簡単な作り方メモ Part2


続きで簡易版XMLHttpRequest監視Extentionを紹介してみます。

Continue reading

Google Visualization APIメモ

まだあんまり使ったことなくて、ちょこっと調べたのでメモメモ。

コードは以下のようにVisualization APIをloadするかたちで使用する。
そのとき使いたい表示コントロールをpackagesに渡す。

もし複数の表示コントロールを使いたい場合は以下のように配列に複数入れると可能。

サンプルコード

行をクリックすれば色が変わるし、列Titleをクリックすればソートされる。
これは便利だな~。

google.visualization.Query

を使ってAjaxクエリを発行できるが、個人的にはこのTable機能単体で使う可能性あり。
Ajaxは別の方法で取得する。

ドキュメントなどなど

本家ドキュメントはGoogle Visualization API - Google Codeより。

和訳もGoogle Visualization API - Using Visualization : Overview の和訳 その1|株式会社 フラッツで見ることができます。

こちらでGoogle Visualization APIを使ったサンプルをコード付きで見ることができます。
AJAX APIs Playground

[via]
はてなブックマーク - monjudohのブックマーク

■参考リンク
Google Visualization APIを早速使ってみた - builder by ZDNet Japan

Rails2のto_jsonで簡単にJSONを返す方法

Rails2からto_jsonというメソッドが使えるようで、Mapに対してto_jsonしてやると簡単にJSON形式で返すことができるみたい。

controller.rb

index.json.erb

index.html

結構Jsonパーサーみたいなのを作るのってしんどいからこうゆうのすごい便利!

■参考リンク
Rails2.1でSWFUploadを使うの続き。JSONでレスポンスの続き - Paradigm Shift Design

Rails2をインストールするときのメモ

rubyのバージョン:1.8.6

Railsのインストール

いつものgemを使ったインストール。

gem install rails

しかしgemが古いとかでエラーが出てしまったのでアップデート。

gem update --system

んでまた、

gem install rails

今度はエラーなし。

rails --version # Rails 2.2.2

入った!

SQLiteのインストール

Rails2.0.2からデフォルトDBがSQLiteになったようなので、SQLiteを入れる。

SQLite Download Pageにコンソール用のexeとdllをダウンロードしにいく。

ダウンロードしたdllファイルとdefファイルをパスが通ってるruby\binにコピー。
(のちのちruby ./script/dbconsoleなんかを使うならexeもコピーしとく)

これだけではSQLiteがrubyから使えないので、sqlite3-rubyをインストール・・・

gem install sqlite3-ruby

がエラーが出た。

C:\_\rails>gem install sqlite3-ruby
Building native extensions. This could take a while...
ERROR: Error installing sqlite3-ruby:
ERROR: Failed to build gem native extension.

c:/ruby/bin/ruby.exe extconf.rb install sqlite3-ruby
checking for fdatasync() in rt.lib... no
checking for sqlite3.h... no

nmake
'nmake' は、内部コマンドまたは外部コマンド、
操作可能なプログラムまたはバッチ ファイルとして認識されていません。


Gem files will remain installed in c:/ruby/lib/ruby/gems/1.8/gems/sqlite3-ruby-1.2.4 for inspection.
Results logged to c:/ruby/lib/ruby/gems/1.8/gems/sqlite3-ruby-1.2.4/ext/sqlite3_api/gem_make.out

調べてみたら因果律量子論 Ruby on Rails nmakeがありませんに解決策が書いてあり、

sqliteのバージョンが新しい物は、ソースインストールみたいなイメージらしくnamekeが必要らしい。
>gem install sqlite3-ruby -v 1.2.3.2.3'

これで、インストールがうまくいくみたいだ。

via: 因果律量子論 Ruby on Rails nmakeがありません

とのことなので

gem install sqlite3-ruby -v 1.2.3

で一つ前のバージョンをインストールした。

プロジェクトの作成

rails hoge -d sqlite3

-d sqlite3」でDBを指定して実行すると、database.ymlがそれ仕様になってくれる。

development:
adapter: sqlite3
database: db/development.sqlite3
pool: 5
timeout: 5000

雛形を作成する。

ruby script/generate scaffold hoge name:string age:integer

んでマイグレーション。

rake db:migrate


以下にアクセスしておきまりの画面が出れば成功!

http://localhost:3000/hoges

■参考リンク
Rails 2.0のscaffoldを使ってみた - idesaku blog
Ruby on Railsインストールメモ - rubyco(るびこ)の日記

JavaScriptでロールオーバーアニメーション Part3

JavaScriptでロールオーバーアニメーションJavaScriptでロールオーバーアニメーション Part2に引き続きであんまり変わっていないんですが、こうゆうのも面白いかも。

今までは高さ20pxのdivタグを横にスライドさせていて、いわゆるプログレスバーっぽさがあったのですが、今回は高さ0pxにしておいて横にスライドするタイミングでじょじょに高さ20pxになるようにしてみた。

続きで動作確認。

Continue reading

JavaScriptでロールオーバーアニメーション Part2

JavaScriptでロールオーバーアニメーションに引き続きマウスオーバー時のアニメーションをJavaScirptで実装しています。


trick7 - ロールオーバー効果へのこだわり2を読んで、dajistudioさんのサイトのアニメーションで気になっていたことがすべて分かった。

たとえばいっきにマウスオーバーした場合は、すこしアニメーションが遅れる。
ただし1つ1つゆっくりとマウスオーバーするとアニメーションに遅れはない。

このレベルは使っている人はほとんど見つけられないと思うけど、なんだか心地よい感じがするのは確かだろうね。
無意識に作用するアニメーションほどかっこいいものはないっ!

なので、この遅延アニメーションをJavaScriptで実装しました。
たぶんタイマーを使っているんじゃないのかな?本家のほうは。

JavaScriptソースコード

jQueryのdataメソッドを使って、マウスオーバーのアニメーションが終わっているのかどうかのフラグ判定しています。
これにより、マウスオーバー直後にマウスアウトしてもアニメーションは終わっていないので、このタイミングで遅延アニメーションを実行します。

続きで動作確認。

Continue reading

JavaScriptでロールオーバーアニメーション

trick7 - ロールオーバー効果へのこだわりを見て、うわ~最後のほうをTweenさせるだけでこんなに気持ちいのかとJavaScript版を作ってみました。

しかし、やっぱりFlashJavaScriptの違い顕著に出てしまったのですがそれっぽくなったと思います。

JavaScriptソースコード

2つのdiv要素を用意しておいて、1つ目の要素にマウスが乗ったときに2つ目の要素をアニメーションさせています。
1つ目の要素を覆うように2つ目の要素が重なるので、そのタイミングでmouseoverが発生してしまうためz-indexでアニメーションする要素を後ろ側に隠しています。

それとanimateメソッドでwidth:0pxからアニメーションするのではなく、いったんcssメソッドを使ってwidth:200pxまで進めておいて、最後の50pxをアニメーションするようにしています。
このひと手間でオモロ~になりました。

続きで動作確認。

Continue reading

カラフルな要素があっちいったりこっちいったり - xyz.js

ちまたで有名なWonderfl Build Flash Onlineをダラ見してたら、これまた面白いFlashを見つけてしまったのでJavaScriptでソレっぽく再現してみました。

↓これがそのFlash。イカス!
code on 2008-12-23 | Wonderfl Build Flash Online
何個かfoakされているので、他の方のを見てみても面白いです。

ただFlashでできることがJavaScriptでできなかったりもするので完璧に再現はしていませんが、一応それっぽく。
JavaScriptでRotationが使えたら要素をグルグル回せるんですがね。

初めcanvasのrotateを使おうかと思ったのですが、座標の記憶とかtranslateとかややこしそうだったので断念・・・

JavaScriptソースコード

実際のActionScriptで使われているTweenerライブラリの部分はjQueryのanimeteメソッド、easing部分はjquery.easingプラグインを使って補いました。

続きで動作確認できます。

Continue reading

マウスから逃げるように文字が移動するJavaScript

monstropolis.org -- intro10

ここ最近画像を動かすことばかりにハマっていたので、こうゆう文字を移動させるのはすごい新鮮でした。

こまかくspanタグで分割された文字がまるでマウスから逃げるように移動するのがとってもかっこいい。
なんかすごい作りたくなったきたw

コードを見てみると、やっぱり複雑な計算が入っててどうしてもこっちが苦手なんだけど、最近Flexに夢中だからどうしてもさけて通れないんだよね〜。

慣れかな?

monstropolis.org -- intro10

IEではbuttonタグのvalueが取れない

2 IEで<button>のvalueを.val()経由で取得できない


IEでは<button value="value">text</button>の内、value="value"の値を$(this).val()経由で取得することができません。


ただ、これはFirefoxでは正常に取得できるため、IEでは通常のDOM経由でも取得できないのかもしれません。


via: jQueryを使うときに気をつけるべき8のポイント : tech.kayac.com - KAYAC engineers' blog

おお~、なんか懐かしいと思ってちょい実験。
buttonタグっていろいろと問題テンコ盛りですよね。

前に記事にしたIEとFirefoxでテキストボックス上でのEnterの挙動についてでもSubmitするときの情報が変動しちゃうし…

サンプルコード

value経由でもgetAttribute("value")でもやっぱりIEではダメでした。

とりあえずW3C見に行ってみたら。
ほ~ら、ちゃんとvalueってあるじゃ~ん。んもうIE。

<!ELEMENT BUTTON - -
(%flow;)* -(A|%formctrl;|FORM|FIELDSET)
-- push button -->
<!ATTLIST BUTTON
%attrs; -- %coreattrs, %i18n, %events --
name CDATA #IMPLIED
value CDATA #IMPLIED -- sent to server when submitted --
type (button|submit|reset) submit -- for use as form button --
disabled (disabled) #IMPLIED -- unavailable in this context --
tabindex NUMBER #IMPLIED -- position in tabbing order --
accesskey %Character; #IMPLIED -- accessibility key character --
onfocus %Script; #IMPLIED -- the element got the focus --
onblur %Script; #IMPLIED -- the element lost the focus --
>
Forms in HTML documents

jQueryを見に行ってみる

とりあえずjQueryで取れないという話だったので、見に行ってみた。
valメソッドは359行目あたりにあります。

おそろしいほど端折りましたが、大体↑の感じ。
やっぱり普通にvalueを返しているんですね。

buttonタグ恐ろしや…

[via]
jQueryを使うときに気をつけるべき8のポイント : tech.kayac.com - KAYAC engineers' blog

Firefox拡張機能(Extention)の簡単な作り方メモ

Firefoxの拡張はJavaScript、CSS、XMLを使うことにより自作することができるのですが、意外と敷居が高くそこまでドキュメントなんかも豊富ではないので、自分用のメモとして簡単な作り方レシピを残してみようと思います。

開発用のプロファイルを作成する

既存のプロファイルで開発してもいいのですが、いろいろ設定をいじることになるのでここでは開発用のプロファイルを作成しています。

  1. Firefoxを閉じる
  2. ファイル名を指定して実行から「firefox -ProfileManager」で起動する
  3. 適当な名前(ここではdev)でプロファイルを作成する
  4. ファイル名を指定して実行から「firefox -no-remote -P dev」で起動する

これで新しい環境でFirefoxがしたと思います。

開発用に設定値を変更する

Firefoxのアドレスバーにabout:configを打ち込んで、以下の4つの値をtrueにします。

  • javascript.options.showInConsole
    • JavaScriptのエラーをエラーコンソールに出力する
  • javascript.options.strict
    • JavaScriptのエラーを厳密にする
  • browser.dom.window.dump.enabled
    • dump関数によってコンソール(Windowsの場合,コマンドプロンプト)へ文字列を出力可能にする
  • nglayout.debug.disable_xul_cache
    • XULのキャッシュを無効にする

■参考記事
Firefox 3ではじめる拡張機能開発:第1回 最小構成でインストール|gihyo.jp … 技術評論社

んでボクの環境では下の2つがなかったので、
C:\Documents and Settings\user\Application Data\Mozilla\Firefox\Profiles\hogehoge.devにあるprefs.jsに以下を直接設定しました。

これでコードを修正するたびにFirefoxを再起動しなくて済みます。

作業ディレクトリを作成する

Firefoxは通常xpiファイルとして配布されますが、コードを修正するたびにxpiファイルにしてFirefoxにドラッグするとなると、
これは相当な面倒になるので、Firefoxには他の場所にあるソースコードをリンクとして読み込むように設定します。

今回は、

C:\_\firefox\hello ←ここが作業ディレクトリ

のようにフォルダを作成して、Firefoxからこのフォルダを見てもらうようにします。

リンクファイルを作成する

先ほどFirefoxにはソースコードのリンクを指定すると説明しましたが、普通Firefoxの拡張は

「C:\Documents and Settings\user\Application Data\Mozilla\Firefox\Profiles\hogehoge.dev\extensions」

のような場所に存在します。
ここにリンクを作成する感じです。

まずはこのディレクトリ内に「hello@xuldev.org」というファイルを作成しましょう。
そしてファイルの中身に

C:\_\firefox\hello

と書いて、先ほどのディレクトリへのリンクファイルを作成します。
これでhelloディレクトリ内にあるソースコードが読み込まれる感じになります。

クロムマニフェスト(chrome.manifest)の作成

chrome.manifestファイルをhelloディレクトの直下に作成し、以下を記述します。

content hello content/
overlay chrome://browser/content/browser.xul chrome://hello/content/hello.xul

chromeパッケージ名とソースファイルの相対パス指定します。
ここのoverlay宣言ですが、これはFirefoxの画面情報としてで読み込まれるchrome://browser/content/browser.xulに対して
chrome://hello/content/hello.xulも追加してちょみたいな感じです。
これにより自分で追加したメニューなどが表示されることになります。

install.rdfの作成

helloディレクトリ直下にinstall.rdfファイルを作成し、以下を記述します。
ここは作る拡張の情報が記載されているファイルになります。

拡張のバージョンや対応しているFirefoxのバージョンなどを記述します。

以下重要なエレメントだけ説明。

em:id
メアド形式かUUIDで指定します。ここは一意にならなくてはなりません
em:version
拡張機能のバージョン
em:type
2:拡張機能、4:テーマ、8:ロケール、16:プラグイン、などなど
em:optionsURL
メニューのアドオン→設定ボタンを押せるようになります

■参考リンク
Install Manifests - MDC

自作xulを作成する前の事前準備

事前準備としてhelloディレクトリ直下にcontentフォルダを作成しときます。
現状前の構成は、

「C:\_\firefox\hello」ディレクトリの直下に

・contentフォルダ
・chrome.manifestファイル
・install.rdfファイル

がある感じです。

hello.xulの作成

contentディレクトリの直下にhello.xmlxulファイルを作成し、以下を記述します。

ここが実際の拡張に対するxulコードになります。
xml形式でボタンやラベルなどを配置できるので、htmlの知識がある人ならピンとくるはずです。
特にイベント登録でonmousedownを使っているのでまさにJavaScriptですね。

ここで重要なのがstatusbarというタグにid="status-bar"を指定していますが、これは適当につけているわけではなく
すでにchrome://browser/content/browser.xulで定義されているid="status-bar"のstatusbarタグに対するオーバーレイになります。
なので、このid指定を間違えるとステータスバーに表示されなくなってしまうので気をつけてください。

どうゆうidが指定されているかの調査方法は↓のほうに書きます。

hello.jsの作成

↑のxmlのscriptタグで外部jsファイルを読み込んでいるので、それを作成します。
contentディレクトリの直下にhello.jsファイルを作成し、以下を記述します。

単にalertを実行しているだけなので、onmousedown='Hello.alert("Hello")'としちゃってもいいのですが、
ここはサンプルなのであえてそうしてます。

またHelloオブジェクトを作成して、その中にalert関数を入れていますが、ここで読み込まれるjsファイルは
グローバルな環境になってしまうので、すでにありそうな名前のオブジェクトを作ってしまうと他の拡張が動かない場合があります。
(Helloも微妙にあぶないですが…w)

なので、拡張に見合った名前のオブジェクトを作成してその中に関数を追加していくようにしましょう!

アドオン→設定ボタンを押せるようにする

contentディレクトリの直下にprefs.xulファイルを作成し、以下を記述します。
常にデフォルトな設定が読み込まれる拡張なら良いのですが、ユーザーに設定値を選ばせる拡張なら設定ボタンを押せる必要があります。

とりあえずラジオボタンで選べるように作ってみましょう。
preferencesタグのidとradiogroupタグのpreferenceは一致するように指定してください。
ここが間違っているとエラーになってしまいます。

現時点では設定ボタンが押せる状態になるだけですが、後で取得する方法を説明します。

Firefxoを起動してみる

ではとりあえずFirefoxを起動してみましょう!
ちゃんと拡張が読み込まれれば、アドオンを追加したときのウィンドウが表示されると思います。

もしアドオンのウィンドウにビックリマークがある場合はどこかの指定が間違っていることになります。

設定で指定した条件を取得する

Firefox起動のテストがOKなら、次に設定で指定したラジオボタンの情報を取得してみましょう。
まずはhello.xulのonmousedown='Hello.alert("hello")'をonmousedown='Hello.alert()'と引数なしにします。

続いてhello.jsを以下のように変更します。

JavaScriptからXPCOMを利用するには,XPConnectという技術を使います。
XPCOMとはFirefox側で提供している機能をまとめたフレームワークになります。
今回は設定画面で設定した内容を取得するので、XPCOM経由で取得する感じです。

またデフォルト値を設定しておく必要があるので、
helloディレクトリの直下にdefaultsフォルダpreferencesフォルダhello-prefs.jsファイルを作成しときます。

その中に以下のコードを記述してください

これをしとかないと、ユーザーが設定画面でOKを押さない限りthis.getPref("hello", "extensions.hello.")の戻り値が
undefinedになってしまいます。

再テストしてみる

基本的にソースコードを修正したら、Ctrl + Nなどで新しいウィンドウを開けば再読み込みされます。
ですが、install.rdfを修正した場合はそれだけではダメなので、一旦Firefox上で拡張を削除してから
もう一度hello@xuldev.orgファイルをドラッグしてあげましょう。


設定画面で選んだ値がalert表示されたでしょうか?(0 or 1)
よっしゃ~~~!

番外編 - browser.xul内のidを特定する方法

オーバーレイのところでもお話しましたが、オーバーレイ対象のidが分からないとxulを書くことができないので
そのidを探す方法を書いてみようと思います。

以下のをアドレスバーに入力してみてください。

chrome://browser/content/browser.xul

Firefoxの中にFirefoxが表示されると思いますw(なんかすごい)

そしたらFirebugを開いてインスペクター(調査)で目的の箇所をクリックすればそこのxul情報が見れるので、
これでidも特定できますね。

Firebug以外にもDOMInspectorでも同じことができるみたいです。

番外編 - デバッグ方法

デバッグをする方法はボクが知る限り3つあります。

・1つ目はalert表示させるパターンですが、これは普通のJSのデバッグでも有用ですが、
for文とかで回している中でalertするとループのたびにポンッと表示されるのでちょっとうざいです。

alert - MDC

・2つ目はdumpを使う方法ですが、これは試したことがないですw
Firefoxを起動時に「-console」を付けたりしないといけないので、これもまたちょっと面倒です。

dump - MDC

・3つ目はエラーコンソールに出力させる方法です
ボクはこれを良く使います。

ただし、この書き方はFirefox3かららしいです。
今まではXPCOM経由でログを吐かなければならなかったようで、実際には以下のコードになります。

こうゆう関数を一個作ってしまえば問題ないのですが、毎回書くのは難点ですね。
しかもlogという名前の関数だと他の拡張とバッティングしそうなので、もう少し工夫する必要もありますしね。

まとめ

ここまでのことが一通りできたら、他にいろいろ応用できそうですね。
ブロガーなら自分の使いやすいようなcopy+の作成や、Firebugに機能の追加なんかもできちゃいます。

ちょっと面倒ではありますが、作ると楽しいFirefox拡張をどんどん作っちゃいましょう!

Part2へ続く。
Firefox拡張機能(Extention)の簡単な作り方メモ Part2

参考リンク

XUL Reference - MDC
XUL Apps > Tips > prefs.js に設定を保存する・設定を読み込む - outsider reflex
Firefox拡張機能(extension)の作り方 ― ありえるえりあ
FireFox Extensionの作り方

Prototypejsのdom:loadedを検証(IEの場合)

いまさらながらPrototype.jsのdom:loadedがIEでDOMContentLoaded的な扱いになるか試してみた。
普通に使わせてもらっているから、ちゃんと動いているんだろうけど何せ擬似なDOMContentLoadedですからね。

Prototype.jsでは3960行目あたりからdom:loadedの部分になります。
んで、IE版のところは3988行目から。

こんな感じです。

scriptタグを生成して、ロードが完了したタイミングでセットされた関数をfireしています。
ここでscriptタグにはdefer属性が指定されているので、このscriptタグの中にはdocument.writeがないことを条件にしています。
つまり、この部分を遅延評価してね~という感じですね。

この遅延のタイミングがDomContentLoadedと同じ?とみなしているようです。

順番としては、

  1. ブラウザがHTMLを上から順番に評価し始める
  2. JavaScriptからscriptタグが追加されるが、defer属性が入っているのですぐに実行しない
  3. 画面全体のDomが構築される
  4. defer属性が付いていたscriptタグの中身が評価される
  5. よってこのタイミングがDom構築完了を意味する

ほんと?w
いやちゃんと動作するんだからそうなんでしょう。
defer属性をこうゆう風に使うなんて、なんかとっても面白いですね。

サンプルコード

少し重めの画像を適当に用意して、さきほどの擬似DomContentLoadedとwindow.onloadの中でalertを表示されています。
これでどっちが先に呼ばれるかが重要ですね。

結果はちゃんと「dom:loaded」→「onload」の順番でした。
ただし、上の画像がない場合など比較的HTML要素が少ない場合ではonloadのほうがdom:loadedより速かったです。
なので画像を使わないテキストサイトとかだとdom:loadedを待つよりonloadを使ったほうがよさそうですね。

ちなみにjQueryのIE版DomContentLoadedは

以下のように、document.documentElement.doScroll("left")が正常に動くまで実行しています。
これを考えた人は本当にすごいですね。
IEContentLoaded - An alternative for DOMContenloaded on Internet Explorer

なぜ、document.documentElement.doScroll("left")でExceptionが発生しないとDomContentLoadedだと思ったんでしょう。

補足

IEscript要素にdefer属性をつけるとinnerHTMLに代入したscriptが実行されるという仕様がある。


via: script要素のdefer属性の実装 - Thousand Years

なんてこともあるみたいです。

FirebugのmonitorEventsでイベント丸見え

いやはやこれは便利だ。
ここ最近全然使っていなかったが、あらためて使うと便利さが理解できる。

サンプル

で特定のエレメントのクリックイベントを監視。

で特定のエレメントのイベント全部を監視。

NodeList[0]とNodeList.item(0)では戻り値が違う

getElementsByTagNameとかで取得したNodeListから参照したいエレメントを削除して、それから中身を見ようとした場合elems.item(0)とelems[0]では戻り値が違う。
まぁ当たり前といっちゃ当たり前かもしれない。

item(0)は関数で指定したノードがない場合にnullを返す、[0]は直接NodeListを見に行ってそこに定義がないからundefinedかな。

とはいっても、

これはちゃんと通るから、大丈夫かな。

このほうが無難かも。

一応DOMの規定では配列のようにアクセスしても、item関数経由でアクセスしてもいいみたいです。

NodeListをforinするとわ~お

ちなみにNodeListをforinとかで回すとえらいことになる可能性があるので、注意が必要です。

これだと欲しいエレメントのpタグ以外に

  • length
  • item()
  • namedItem()

が取れちゃうから。
なので、普通にfor文で回したほうがよいですね。

高速化するなら

NodeListやHTMLCollectionに直接アクセスするより、一旦静的な配列にしたほうが速い - 素人がプログラミングを勉強するブログ

一旦配列に突っ込んだほうが速いようです。
意外や意外!

ブラウザごとのJavaScriptアニメーション比較

ここ最近JavaScriptでアニメーションする機会が結構増えてきたのですが、やっぱりブラウザによって速度というか動きがかなり違うので、その比較をメモメモ。

IE6.0

IE6.0は以外にもアニメーション処理は速いというか滑らかです。

前にもJavaScriptでアニメーション(animate)するときに気をつけたいことで紹介しましたが、中に画像がたくさんあるdivタグmargin-leftとかでアニメーションすると激重になる可能性があるので注意が必要です。

position:absoluteでのアニメーションはかなり調子良いです。

IE7.0

比較的問題がないブラウザです。

marginを使ったアニメーションにも強いですし、opacityを使って透過してフェードアウトとかにも強いです。
IE7.0は重い重いという話が良くありますが、アニメーションに限ってはなかなか出来るやつですw

Firefox2.0

これが一番曲者かと。

アニメーションする際に対象のdivタグがoverflow:autoになっていると、すごいチラ付きが発生しますし、アニメーション処理自体にもモッサリ感があります。

このoverflowの話は結構面倒で、今まではIEとIE以外のJSコードを分ける処理は結構書いていましたが、Firefoxの場合にもoverflowをhiddenにしたりautoにしたりと独自実装になる感じです。

Firefox3.0

Firefox2.0と比べるとまぁ良いのですが、タブをいっぱい開いていたりFirefoxのメモリ使用量が多いとアニメーション時にもたつく感じがあります。(これはFirefox2.0も同じです)

こちらもoverflowは対策が必要です。

Opera9

Operaのアニメーションはとてもきれいです。 margin、positionとも滑らかにアニメーションします。

ただLightBox風のJSを作る場合に、レイヤーを貼った上にボックスを表示してその表示方法がアニメーションのときにはちょっと注意が必要です。

input type="button"を押したらボックスを表示するとして、レイヤーが表示され始めているのにレイヤーの後ろにいるbuttonを押せてしまう場合があります。

つまりレイヤーが表示されたタイミングでbuttonのonclickをfunction(){}(つまり空)にしてやるとか、それ以外でフラグを使ってすでに押されていることを把握する必要があります。
(※これは画像ボタンにすることで解消されるかも?未検証)

Safari3.1

完璧なブラウザです。

特にアニメーションに限っては文句の付けようがない感じです。
Safariの欠点は、Safariでは画像のloadが終わっていないとwidth、heightがうまく取得できないでも紹介しましたが、jQueryのreadyではDOM構築が終わっていない場合があるので、アニメーションさせたい対象のエレメントの幅を取得したい場合はonloadを待つほうが無難かもしれません。

Google Chrome

Safariと同じWebkitベースのブラウザなので、同じくキレイです。

ただ、ちょっと未確認なんですがJSファイルをBOMありのUTF-8で保存した場合に、うまくJSファイルを読み込んでくれなかったです。

他のブラウザでは問題なかったのですが、Google Chromeだけで発生しました。
対応としては、BOMなしのUTF-8Nとかで保存しました。
う~ん。

Netscape7

アニメーションはFirefox2.0よりは滑らかに感じますが、やはりちょっと微妙です。

各ライブラリがNetspaceに対応していないのもあり、opacityの透過などは自前で容易する必要もあったりします。
一応Netscapeではfloatしているブロックにrelativeをかけても効かないでちょっとした欠点も載せているので参考にしてください。

これ以外にアニメーションと関係ないですが、CSSで
background: url(/hogehoge.gif) no-repeat left 7px;
みたいにピクセル単位で座標を指定する場合がありますが、これにはNetscapeは対応していません。
いろいろ試してはみたのですが、ダメでした。
なので、
background: url(/hogehoge.gif) no-repeat left center;
などで対応。

まとめ

全ブラウザで同じように見せるスタイルシートも大変な作業ですが、JavaScriptを使ったアニメーションもブラウザの個性に対応しないといけないので、まだまだクロスブラウザ対応は必要そうですね。

Ajaxのオブジェクト(XMLHttpRequest or Msxml2.XMLHTTP)や基本的なDOM操作はライブラリが吸収してくれますが、アニメーションに限ってはどのスタイルを使ってアニメーションをするかは自分で決めなきゃいけないので、これからいろいろ調べていきたいと思います。

とはいってもjQueryのanimateメソッドにはすっごく助けられていますがw

■参考記事
jQueryのanimateメソッドの使い方
JavaScriptでアニメーション(animate)するときに気をつけたいこと

Netscapeではfloatしているブロックにrelativeをかけても効かない

ネスケのクロスブラウザ対応なので、あんまり必要はないかもしれないですが、
一応こんな現象を発見したのでメモメモ。

以下のように外枠のブロックに「float: right;」と「position: relative;」が掛かっている状態で、
中にいるブロックに「position: absolute;」で絶対配置にしています。

こうゆう例はちょっと珍しいですが、中にいるブロックが複数あってz-indexで切り替えるときとか
こんな感じかと思います。


んで、上の例だとネスケではrelativeが効かず、画面の左端に中のブロックが移動してしまいます。

これを解消するには「float」と「position」を別々のブロックにしてあげるとうまくいきます。

解決策

何かと何かを一緒のブロックに指定するとうまくいかないケースはIEだけかと思っていましたが、
以外にもネスケでこうゆうパターンがありました。

参考までに!

onloadを待たずに特定のエレメントに処理を実行する方法

ちょっとonloadを待たずに処理するのはどうやろう・・・みたいな疑問が沸いたのでメモメモ。

onloadイベントはwindowオブジェクトやimgタグ、scriptタグなど特定のものにしか存在しないので、擬似的に対象エレメントのDOM構築が終わったかどうかの判定ができません。
onload

なのでタイマーを使ってエレメントが取得できるまで繰り返し、その後に処理を実行するという方法ならDOM構築完了時に処理が実行できそうです。

たとえば上記のようなエレメントがあって、ここからid="hoge"のinnerHTMLをonloadイベントを待たずに取得したい場合は
以下のように書く感じです。

特定エレメントのidプロパティが取得できたらDOM構築が完了と考えていますが、もしかしたらこれだけだと判定としては弱いかもしれません。
ここは要調査!

画面の高さが結構ある画面なんかで画面初期でselectboxをdisabledにしたい~というときにonloadを待っているとかなり時間が経った後にdisabledになるので、こうゆう方法もありかもしれません。
DomContentLoadedでもそこそこ時間がかかるはずっ。

※divタグ自身にonloadがあったらな~。

jQuery Pluginの書き方

※10/14 もう少し詳しく書いてみる!

jQueryのプラグインなんかを書き始めると、どうゆう風に記述するかいろいろ人によって違うのでちょいとまとめてみました。
おそらくこれ以外にもありそうですが、比較的メジャーな感じで並べています。

jQueryには
  1. ①$("#hoge")で取得するオブジェクト
  2. ②jQueryオブジェクトそのもの

と2つのオブジェクトが存在します。
違いは①のほうは「$("#hoge").hogehoge();」という感じで書くことができ、②のほうは「jQuery.hogehoge();」とちょっとしたユーティリティのように書けます。
メソッドが実行されるタイミングで対象のエレメントが特定されてて欲しいなら①、そうでないなら②みたいにボクは使っています。

これを踏まえて以下のコードはjQueryオブジェクトにそのまま追加するパターンとして紹介しています。
もし①で使えるように追加するなら「$.fn.hoge」というようにfnを途中に追加してください。

一般的な書き方

よく見るコードはこの書き方かと思います。
関数の中では$で記述できるので比較的楽です。

ちょっと普通な書き方

これは1番目とあんまり大差はないですが、これも$で書けるのでまぁ楽チン!

jQueryオブジェクトをそのまま使う書き方

これは毎回jQueryドットと書かないといけないので、ちょっと面倒。
やっぱり1番目のほうがスマートですかね。

関数スコープに閉じ込めない書き方(これは良くない)

う~ん、これはjQueryっぽさがなくなっちゃうし、関数の外で書いた変数はスコープグローバルになっちゃうし・・・
バッドノウハウですねw


あと肝心なもう一個を記述し忘れてましたw

extendを使う書き方


以下jQueryの解説スライド。
こうゆうのをちょっと覗いてみるのも面白いですよ!

UTF-7でスクリプトを実行させるXSSについて

IEでUTF-7なスクリプトをiframeの中に表示するとXSSが発生するメモです。
あんまりこの話には詳しくないので、今後の調査材料として残しときます。
(※一応悪用厳禁であります!)

iframe内のエンコードが正しく指定されていない場合は、そのiframeの親にあたる部分のエンコードが自動的に適用されるというIEのバグがあるみたい。
今回はそれのちょこっとした検証!

1番初めに呼ばれるhtml(①.html)

iframe内で呼ばれるGetメソッド

結果

doGetメソッド内でエンコードを正しく設定せずにレスポンスしているため、IEでalertが表示される。

その他の実験まとめ

  1. 「①.html」ではなくiframeのパスを直接呼んだ場合はscriptは実行されない
  2. 「①.html」にmetaタグを正しく指定すればscriptは実行されない
    <meta http-equiv='content-type' content='text/html;charset=utf-8'>
    ただしutf-7を指定した場合はscriptは実行される(まぁそうだろうな)
    <meta http-equiv='content-type' content='text/html;charset=utf-7'>
  3. サーバー側でエンコード指定してもIEが解釈できないエンコードの場合はscript発生
    arg1.setContentType("text/html");
    arg1.setCharacterEncoding("utf8");	//正しくはutf-8
    
  4. 当たり前だがiframe内のhtmlに正しくmetaタグを指定すればscriptは実行されない

このお話はなかなか奥が深くてむずかしいですね。
とにかくIEに依存した Webアプリケーション セキュリティのプレゼン資料を見て勉強するしかなかそうです!


■参考にさせていた資料
IEに依存した Webアプリケーション セキュリティ
そろそろ UTF-7 について一言いっとくか - 葉っぱ日記
まだまだあるクロスサイト・スクリプティング攻撃法:ITpro
36. UTF-7とクロスサイト・スクリプティング:ITpro

(function(){})()の代わりにnew function(){}って方法もあるよ

だいたいは①の方法で即時実行な無名関数を作ると思うんですが、②みたいに書くこともできる。
でもボクはやっぱり①の書き方のほうが好きだな〜。

ただし、②の使い方にはちょっと気をつけないといけないです。
というのも②はfunctionをnewしちゃっているので、この関数はコンストラクタになってしまうこと。
なので以下のようにその関数が属するオブジェクトが変化してしまします。

もうちょい分かりやすく書くと以下の感じ。

func2のほうはnewした段階でコンストラクタが呼び出されるので、thisが代入先のobjに切り替わる。

ということでやはりnew function(){}よりも(function(){})()のほうが無難そうですねw
jQueryなんかもコード全体を(function(){})()で囲って、スコープを関数内に閉じ込めたりしてるし。(理由になってない!)

canvasを使って波紋が広がるripple.js作りました

ripple

canvas使って何かしたいな〜と思っていたら、波紋を描いたらちょっと面白いかもと思ってこんなJavaScript作ってみました。
あんまり深いこと考えてないですw

マウスの移動に波紋が付いてきます。
またクリックすると少し大きい波紋が広がります。

一応コードは以下の感じ。
canvasを使って丸を描いてます。(すごいシンプルっ!w)

またイベントのセットは以下のようにmousemoveclickに割り当ててます。
すいません、今手元にIEがないのでIEのチェックだけ出来ていないです。多分以下のコードで動くような〜。

Eventが発生するたびにマウスの座標をRippleクラスに渡しています。その後drawメソッドで描画しています。

とりあえず触ってみてください。
ripple.jsを触ってみる

ちょっと気に入っているのはこういったアニメーションするときに少し描画を遅らせるとそれっぽくなる気がします。
なので、マウスを移動したときに少し遅れて波紋が付いてくると思います。
こうゆうの結構好きです。

ソースは以下からダウンロードできます。
ripple.js


他にもこんなん作ってます。どうぞよろピク。
キングボンビーがサイトを侵略する?jQuery Plugin - kingbonbi.js作りました
なんかものが落ちるjQuery Plugin - JDropper作りました

Chromeのユーザーエージェント

一応メモ。
Webkitやね〜。

Mozilla/5.0 (Windows; U; Windows NT 5.1; en-US) AppleWebKit/525.13 (KHTML, like Gecko) Chrome/0.X.Y.Z Safari/525.13

[via]
CyberAgent SEO Information

WebkitのDOMContentLoadedはDOM構築が完了していないかもしれない

Safari3.1でDOM構築が終わったタイミングでイベントを登録していたのですが、うまくいかなかったときのお話です。
jQueryを使っていたので自動的にDOMContentLoadedイベントに登録されると思っているのですが、これがどうもDOM構築が終わっていないんじゃないかと。

それが判明したのが、画像をスライドするパーツを製作していたときにスライド対象のdivタグのwidthを取得していて、このwidthがなぜかSafari3.1だと小さく取得されました。

以下にその例を載せて起きます。

SafariのDOMContentLoadedで失敗したパターン

画像がたくさん並んだボックスを左や右へスライドさせるときに、何枚あるか分からなかったので画像が入っているボックスのwidthを取得して計算をしていました。
以下にサンプルのHTMLを載せています。

このページの全体の高さは2500pxほどあります。ちょっと縦長なページ。
わけあってdivが2階層いますが、スライドさせる対象のエレメントはulタグになります。
このulのmargin-leftやmargin-rightを変更することによって画像がスライドしているように見せる感じで作っていました。

んで画面のDOM構築が終わった段階で、ulタグの幅を取得しようとしたのですが、なぜかSafari3.1でだけwidthが少なかったのです。
たとえばFirefox3では1000pxあったのに、Safari3.1では650pxとか。
かなり中途半端なwidthが取れていたので、これはもしやDOM構築終わってないんじゃ?
と思ってwindow.onloadにfunctionをセットしてみたところ・・・


「Safari3.1でもwidthが1000pxで取得できました。が~~~ん」

jQueryのreadyの中身について

久々にjQueryのreadyの部分を追ってみました。
bindReadyというメソッドが2329行目あたりにあります。
その中に以下の記述があるのですが、これは「webkit nightlies currently support this event」とコメントされているとおりSafari3.1ではDOMContentLoadedがあるのでif文に入ります。
参考リンク:Changeset 26101 -- WebKit -- Trac

そしてこのDOMContentLoadedを登録しつつ、その先に進みます。
2366行目あたり。

ここでSafariの場合に2つの方法を使ってDOMContentがLoadedになったかを確認しています

まずdocument.redayStateがloadedかcompleteになるまで自分自身の関数をループします。
ここのチェックが終わったらstyleタグとlinkタグの合計数とdocument.stylesheets.lengthが一致するまで繰り返します。

これら2つの条件をクリアしたらやっとDOMContentがLoadedになった状態とみなすようです。
なかなか複雑ですねw

ここでちょっと気になるのですが、Safari3.1では「DOMContentLoaded」がありますが、その後の「if ( jQuery.browser.safari ) {」にも入ってしまうのです。
なので2重のほうほうでDOM構築を待つ感じになっています。どっちのほうが速いの?w

ちょろっと簡単にテストしてみました

上記のコードを実行した場合の挙動が少しへんでした。
まずDOMContentLoadedでjQuery.readyが登録され、その後のSafariの分岐でdocument.readyStateの状態を監視します。
するとdocument.readyStateのif文には約1回くらいしか入らず、その下にあるif文には一切入りませんでした。

順番にしてみました。

  1. DOMContentLoadedにjQuery.readyを登録
  2. Safariの場合にdocument.readyStateを監視
  3. DOMContentLoadedイベント発生でjQuery.isReadyがtrueになる
  4. document.readyStateを監視しているがjQuery.isReadyがtrueなのでループを抜ける
  5. だからdocument.stylesheetsのlengthチェックが走らない

う~~~ん・・・
だとするとSafariのDOMContentLoadedのほうがjQueryのDOM構築待ちより速いということでしょうか。
速い故にまだ構築し終わってない?w
まさかね!

まとめ

かなりイレギュラーなパターンだと思いますが、Safariでこういう現象があったのは確かです。
なのでwindow.onloadを待つか、documentのDOMContentLoadedを待つかはテストしながら判断したほうがよいかもしれません。

Firefox3.0やIE7、IE6では特に問題がなかったです。
SafariのDOM構築って少しくせがあるので、そこが悩みどころですね。
レンダリング超速いですが・・・

JavaScriptで単体テストをするならQUnitはいかが?

「JavaScriptのテストってわざわざXUnit系を使ってまでする必要はない!」
みたいな意見は多々あるのですが、ライブラリなどを作っているときには非常に便利だったりします。
ちょこっとした修正がどの程度影響があるか分からないときに、テスト用のコードをしっかり書いてあればそれを実行するだけですんでしまいますからね。

そんで最近になって
JavaScript--単体テスト環境の選択肢 - builder by ZDNet Japan
という記事を見てて、「あれ?Qunitがないぞ!」と思ったので簡単に使い方を書いてみたいと思います。

上記リンクの記事ではJsUnitRhinoUnitのことが書かれていますが、これらはJavaありきというかANTありきなので、ちょろっとテストコードを書くというスタンスにはなかなか難しいと感じています。
ただJsUnitは全ブラウザを登録しておけば、いっきにクロスブラウザのテストを実行してくれるので便利といえば便利なんですけどね。

その点QUnitはjQuery用のテスティングフレームワークなので、コード量も少なく簡単にテストコードを書いていけます。
(少しだけjQueryに関する知識が必要になってきちゃうのはご愛嬌)

jQueryを使ったテスティングフレームワークですが、別に自作のライブラリのテストももちろんできますので、開発で使っているライブラリをテストすることができます。

使えるメソッドいろいろ

QUnit - jQuery JavaScript LibraryのAPI documentationのところに使い方が書かれていますので、ここではよく使いそうなメソッドだけを説明したいと思います。

test( name, test )

nameにはテスト名、testには実行したいテストコードを匿名関数で記述します。

module( name )

nameにはテストしたい単位を渡します。これはテストをしているときの目印になります。
たとえばレイヤーを操作するテストをしたい場合に

としておくと、テスト結果画面で
「レイヤー表示テスト module: レイヤーの枠を表示する (0, 1, 1)」

みたいにmoduleの手前にプレフィックスが表示されます。

ok( state, message )

stateにはfalseとtrueを指定できます。
falseの場合にはNG、trueの場合にはOKとなります。
これは帰ってきた値がtrueかfalseか、または通過したかしないかなどの判定に使えそうです。

messageは表示したい文字列を渡します。

equals( actual, expected, message )

これはよく使うやつですね。
actualとexpectedの値が同じ場合にOKとなります。

messageは表示したい文字列を渡します。


すぐに使いそうなのをご紹介しましたが、もっと詳しく知りたい場合にはjQueryのテスティングフレームワークQUnit (でぃべろっぱーず・さいど)をごらんください。
「提供されているメソッド」に詳しく書かれています。

QUnitのダウンロード

QUnit - jQuery JavaScript LibraryのUsing QUnitのところにjsとcssのリンクがあるのでここからダウンロードできます。

ダウンロードするのが面倒というかたは次の「QUnitを使ってみる」に進んでください。

QUnitを使ってみる

以下がQUnit用のHTMLになります。
ここにテスト結果がどんどん表示される感じです。

もしQUnitをダウンロードされた方はtestsuite.cssとtestrunner.jsのパスを変更してください。

今回はテスト用のコードを「qunit.js」に、テスト対象のコードは「hogehoge.js」として話を進めていきます。

テストしたいコードは以下になります。

文字列を返してきているので、これはequalsでチェックできそうです。
なので、qunit.jsには

と記述してテストを実行してみました。
実行結果は以下の画面になります。

failedが0になっているので、バグはなさそうですね。
おそらく大体がこういったテストで十分だと思うのですが、もしHTMLエレメントを使ったテストの場合には少し工夫が必要です。
どっかのdivタグのinnerHTMLを書き換えたテスト、id指定で取得したエレメントのwidthのテストなどはどうしてもHTMLを必要とします。
次はHTMLエレメントに対してテストをする場合を解説してみたいと思います。

HTMLエレメントに対するQUnitテストコードを書いてみる

今回はHTMLエレメントを透過させるメソッドをテストコードを書いてみました。
初めに必要になるファイルを解説します。

  1. qunit.js - テストコードが記載されているファイル
  2. hogehoge.js - テスト対象のコードが記載されているファイル
  3. opacity.html - 透過のテストをするときに使うHTML

透過に関するテストって自動でできるの?と考える方がいらっしゃるかもしれませんが、これが以外とできるんですw

先ほど使ったQUnitテスト結果HTMLは、あくまでもテスト結果を表示するものなのでこれとは別にHTML(opacity.html)を用意します。

まずは透過させるコードです。

これのテストコードは以下になります。

ここからがちょっと新しいテストコードになります。
テストコードの中でtestwinというメソッドを呼んでいます。これは新しくウィンドウをPopupさせ、そのHTMLの描画が完成した瞬間にテストコードを実行してくれるすぐれものです。
つまりopacity.htmlを新しいウィンドウで開いてDOMの構築が完了したら透過のテストコードを実行してくれる感じです。

これはjQueryのoffset.jsの中を参考にしています。

続いてopacity.htmlの中身。

ここではjQueryのファイルとテスト対象のhogehoge.jsを読み込んでいます。
そしてscriptタグで「$(function(){});」を実行しています。
先ほどのテストコードでPopupした画面のDOM構築を待つと解説しましたが、これはつまりjQueryのjQuery.isReadyがtrueになるのを監視しているのです。
jQuery.isReadyはreadyというメソッドが呼ばれて初めて監視がスタートされるので、ここで$(function(){});を実行しているのです。
ちょいややこしいですねw

これでテストするためのコードがそろいましたので、実行してみたいと思います。

おお~Opacityのテストが実行されました。
$w("#opacity").setOpacity(0.2).getOpacity()で返ってきた結果が0.2なのでちゃんと透過機能がはたらいたようです。

まとめ

HTMLエレメントのテストで別のHTMLファイルを作らないといけないのはちょっと不便かもしれませんが、1回作ってしまえば後は何度でもテストが可能ですので、いつかきっとプログラマーを助けてくれると思います。

QUnitはJavaやANTなどが不要なため、完全に独立したテスティングフレームワークとして使えるので
「JSでテストコード書きたいけど敷居が高いな~」
という人にはもってこいなのではないでしょうか?

良く分からないこと

IE7.0でウィンドウを開いてテストするときに、まれにうまくいかないことがあります。
F5とかで再度テストをすれば大丈夫ですが、そうゆうときもあるようです。
Safari3.1やFirefox3では特に問題なかったです。
でもなぜIEだけ・・・

■関連リンク
Getting Started With jQuery QUnit for Client-Side Javascript Testing - Chad Myers' Blog
jQueryのテスティングフレームワークQUnit (でぃべろっぱーず・さいど)

onunloadイベントが拾えないパターン

onunload時に何か処理を実行して、その処理がとっても大切な場合は以下のパターンのときに
注意する必要があるかもしれないというメモ。

リンクを押して他の画面に遷移した場合

Firefox3.0
OK
IE6.0
OK
IE7.0
OK
Safari3.1
OK
Opera9.5
OK


F5を押した場合

Firefox3.0
OK
IE6.0
OK
IE7.0
OK
Safari3.1
OK
Opera9.5
NG


ブラウザを閉じた場合

Firefox3.0
OK
IE6.0
OK
IE7.0
OK
Safari3.1
NG
Opera9.5
NG

JavaScriptからOpacity(透過)を設定する方法

JavaScriptでアニメーションさせようとしたとき、意外と使うのがこの透過。
じょじょに透過させていくとか、見栄えもかっこよくボクは良く使います。

でも既存ライブラリを使った場合、Netscapeに対応していない場合が多いです。
jQueryPrototype.jsはそもそも対応ブラウザにNetscapeが含まれていないので当然といえば当然ですね。
それでもNetscape対応させたい場合のメソッドを作ってみました。
すんごい短いコードですw

一応ライブラリごとのOpcityの設定について書いておきます。

jQueryからOpacity

PrototypeからOpacity

自作メソッドからOpacity

3パターンのOpacity設定を使って、どのブラウザでも透過ができるようになっています。

JavaScriptやCSS、Railsなど使えそうなチートシートいろいろ

Cheat Sheets - Added Bytesで開発に役立ちそうなチートシートが公開されています。

PDFで落とすことができますが、PNGもあるのがありがたい。

チートシートもみやすく前にPrototype.jsのチートシート(ver1.5、1.6)で紹介したものを合わせてどこかに貼っておけばきっと開発を助けてくれるはず。


JavaScript Cheat Sheet


JavaScript Cheat Sheet - Cheat Sheets - Added Bytes

CSS Cheat Sheet


CSS Cheat Sheet (V2) - Cheat Sheets - Added Bytes

JavaScriptライブラリ毎のSelectorAPIの速度一覧

普段はPrototype.jsjQueryを使ってJavaScriptを書いているのですが、そこまで複雑なCSS SelectorAPIは使ったことがないのでこうゆう一覧、というか実際に実行して確認できるのはありがたい。

SlickSpeed Selectors Test

SlickSpeed Selectors Test

検証してくれるJavaScriptライブラリは以下のとおり。

  • DOMAssistant2.7.2
  • jQuery1.2.6
  • Prototype1.6.0.2
  • Mootools1.2
  • ExtJS Core2.2
  • Dojo1.1.1
  • YUI2.5.2

MacのSafari3.1で試してみたのですが、DOMAssistantというライブラリがおそるべき速さで実行できています。
もっとも遅かったのはYUIですが、Prototypeもそれに負けずに遅い感じでした。

jQueryはさすがですが、Extに負けているのがビックリ。

いろんなブラウザで試せばこれで一通りのベンチマークになりますね。
とはいっても複雑なCSS SelectorAPI書くより、idふるなり適当なclassを割り当てたほうが良さそうですねw

addEventListenerとattachEventでは実行される順番が違う

たとえばPrototype.jsを使っている場合、

こんな感じでイベントを登録することができる。
また同じオブジェクト(window)に対して同じイベント(load)を指定した場合は、追加として登録される。
なので上書きはされない。

こうゆう場合にIEとIE以外では挙動が違うので一応メモを残しておきます。

IEのattachEventの実行順序

一番最後に追加されたイベントから一番最初に追加されたイベントにさかのぼるように実行される。

なので上記のコードでは2→1

IE以外ののaddEventListenerの実行順序

一番最初に追加したイベントから一番最後に追加されたイベントを実行される。

なので上記のコードでは1→2

まとめ

初めPrototype.jsが何かしているのかと思ったのですが、とくにそれっぽい箇所がなく以下のように自作した関数でも再現したため、こうゆう挙動は一般的なんでしょうね。

一番最初に登録したイベントから実行されるのを望む場合はIEとIE以外で挙動が違うのでハマる危険性がありますね。

追記:
IEのイベント実行順序は不定? - inamenaiの日記でさらに実験をしていただきました。
attachEventは単純に逆順になるわけではなくランダムだそうですw
でも何度か実行しても同じ順序になるようなので、何か法則でもあるんでしょうか・・・

CSSファイル内に他のCSSファイルをインクルードする方法

ひとつのCSSファイルを共通部分をあの画面とこの画面とかで共通で仕様したいがlinkタグを追加したくないとかに便利。

読み込むCSSは1つのファイルなのに、CSSファイルの中から別のCSSファイルをインクルードしてくれるので、2個のCSSファイルを読み込んでくれる。

index.html style.css include.css


あんまり使う機会はなさそうですねw

DOM Events - DOMAttrModifiedを使ってみる

イベントを登録されたオブジェクトの属性が変更された場合にfireされるイベント。
Document Object Model Events

あるHTMLオブジェクトの属性を監視するときに便利かもしれませんね。

setIntervalで監視しているのをこういったイベントに置き換えることによって、簡略化もできるし。
でもFirefox限定・・・

DOM Events - MDC

DOMとJavaScriptについて

DOM(Document Object Model)とは、HTML文書およびXML文書のためのAPIである。」
というのがDOMの説明に多いのだが、一体何がDOMで何がDOMではないのかを判断するのがちょっぴり難しい。

JavaScriptをコーディングしていて、「あ~この部分はDOMだな」とか「う~ん、ここはDOMではなくJavaScriptだな」とかを明確に判断する必要はないんだけれど、分かればもっと楽しくなるんじゃないかな。

なのでDOMで遊ぶ際に必要な知識なんかを以下にまとめてみました。
既知の情報も多々ありますが、個人的なメモなのでご了承ください。

DOMとは?

HTML(XML)のようなタグ構造を持つ文書に対して、あたかもオブジェクトのようにアクセスするためのAPIです。 HTMLはタグという文書構造になっているので、例えば「
」のようにidにhogeという文字を持つdivタグにアクセスしたいとしたとき、その方法を提供してくれるのがDOMの機能です。 document.getElementById - MDC

文書の構造なのにJavaScriptからオブジェクトのようにアクセスできるのはとっても大切で、表示している文字列を書き換えたり背景色を変更したり、アニメーションさせたりといろんなことができてとっても楽しいのです。

そういった便利な関数やプロパティはオブジェクトとして提供されDOMインターフェースというものを通じてボクらはアクセスすることができます。

たとえば以下のようにtableタグを作るためにdocumentオブジェクトが持つcreateElementメソッドを使ったとしましょう。
この場合var宣言で定義されたobjには何が入っているのでしょうか?

JavaScriptでいうところのオブジェクトなのには変わりないのですが、new Object()とした場合と今回のようにcreateElementした場合ではオブジェクトの中身が全然違います。
「HTMLTableElementというDOMインターフェースを実装したtableオブジェクト」というのがobjに入っているオブジェクトの正体ですね。
(なんだか長ったらしいですが・・・w)

createElementでtableオブジェクトを作った場合にはinsertRowというメソッドを持ちますが、new Object()ではそのようなメソッドは持っていません。
これはHTMLTableElementインターフェースを実装しているかそうでないかの違いです。
HTMLTableElement (Common DOM API)

DOMって他の言語でも使えるの?

DOMの機能はPerl・Java・ActiveX・Pythonなどで提供されているようです。
確かにXMLを読み込むような処理の場合にDOMが使えれば簡単にアクセスできますもんね。

PythonのDOMを使った例

# Python DOM example
import xml.dom.minidom as m
doc = m.parse("C:\\Projects\\Py\\chap1.xml");
doc.nodeName # DOM property of document object;
p_list = doc.getElementsByTagName("para");


via: 導入編 - MDC

JavaのDOMを使った例

初めにXMLの読み込み処理がありますが、それ以降はほとんどJavaScriptで使ったものと同じですね。

このようにDOMは他の言語でも提供されているありがた~いオブジェクトなわけです。
これもDOMというものを中立に考えて機能を実装してくれているからなのでしょう。

何がDOMで何がJavaScript?

ここが本題といったところでしょうか。
どこがDOM?みたいに疑問を持つことは普段のコーディングにあんまり影響はしませんが、たとえばwindow.alert()ってDOMなの?そうじゃないの?みたいに少し突っ込んでみると興味が沸いてくると思います。

alert() は引数の文字列が入ったダイアログをポップアップする DOM のメソッドです。


via: The DOM and JavaScript - MDC

とmozillaで解説されているので、これは間違いなくDOMの機能でしょう!

では以下でDOMの場所を特定して解説してみたいと思います。
なおThe DOM and JavaScript - MDCのDOM と JavaScript - 何が何をしているのか?を参考にしています。というかほぼ一緒!


サンプルコードたったこれだけです!w
これだけあれば十分です。

var obj =

ここはobjというJavaScriptの変数を作成しています。

document.getElementsByTagName("div");

Documentインターフェースを実装しているdocumentオブジェクトのgetElementsByTagNameメソッドを使ってHTMLページの順番でdivタグを取得しています。
ここで取得されるオブジェクトはNodeListインターフェースを実装している配列になります。
なのでlengthというプロパティを持ってはいますが、これはJavaScriptの配列のlengthとは違います。
NodeListインターフェースが提供しているlengthとJavaScriptが提供している配列という違いですね。

alert(

DOMの機能を使ってダイアログを表示します。
(今までにこのメソッドを何度使ったことか・・・最近はconsole.logになりつつありますが)

obj.item(0).id);

ここはちょっぴり複雑ですね。
まずobjにはNodeListインターフェースを実装した配列が入っています、そしてその一つ一つにはHTMLDivElementインターフェースを実装したオブジェクトが入っています。
NodeListインターフェースにはitemというメソッドがあり、引数に数値を指定することでdivオブジェクトを取得することができます。

そして取得したdivオブジェクトが持つidというプロパティにアクセスしていますね。
idというプロパティはElementインターフェースが提供しているプロパティです。
ということはHTMLDivElementインターフェースとElementインターフェースを実装しているということになります。
(2個も実装しているなんてなんて贅沢なっ!)

基本的なclassName、id、innerHTML、styleなどは確かにどのHTMLオブジェクトでもアクセスできるので一元的にElementインターフェースで実装しているんですね。
ほほぅ。
element - MDC

たった2行のJavaScriptを見てみましたが、こんなにもいろんな実装がされているなんて!といった感じでしょうか。
先のコードでDOMじゃない部分といえば、変数宣言のvar obj部分と;セミコロンくらいです。
それ以外が全部DOMで提供された機能だったというわけです。
DOM様様ですねw

まとめ

なんとなくDOMについてまとめておきたかったので今回の記事を書きましたが、結構ボリューム感がありました。
とはいってもmozillaのサイトに行けば、JavaScriptの仕様はたいてい記載されていますし、今は詳しく書かれた本もたくさん発売されています。
勉強するにはもってこいな時代ですね。
6年くらい前はまだAjaxもそんなに普及されていなくて、そもそもAjaxという言葉はなかったからずうっと「非同期」なんて呼んでいたりしました。
その当時はwindow.alertはDOMの機能だってことは、どこにも書いてなくて先輩とかに聞いて回ったのを覚えています。

なんかものが落ちるjQuery Plugin - JDropper作りましたで作ったオモロ~なプラグインもDOMの機能なしには語れないのです。

DOMを学びやすいJavaScript解説本

JavaScript 第5版
JavaScript 第5版
posted with amazlet at 08.09.02
David Flanagan
オライリー・ジャパン
売り上げランキング: 7060

やっぱりサイ本はかかせないです。
この本は重要なところを太字とかにあんまりしてくれていないので文章を読む感じで学習するのが得意な人に向いているんじゃないでしょうか。

Head First JavaScript 頭とからだで覚えるJavaScriptの基本
Michael Morrison
オライリージャパン
売り上げランキング: 4564

この本最近買ったのですが、アツいですw
イラストばんばん使いまくりで、クロスワードとかも途中にあって、学習というより遊びながらな印象があります。

まるごとJavaScript & Ajax ! Vol.1
天野 仁史 舘野 祐一 川崎 有亮 arton 田中 孝太郎 国分 裕 山本 有悟 海野 裕也 nanto_vi
インプレスジャパン
売り上げランキング: 125084

かゆいところまで突っ込んで解説されているので、かなりな良本です。
雑誌感覚なので、気軽に読めるのもいいですね。


■関連リンク
W3C Document Object Model
Gecko DOM Reference - MDC
org.w3c.dom (Java 2 Platform SE 5.0)

Arrayをforinするより普通にfor文で回すほうが速い

Arrayのlengthはいったん変数に格納してからループしたほうが速いに引き続きベンチマーク。

そういえば配列をforinで回したことがあんまりなかったので、普通のfor文とどっちが速いのかな~という疑問が沸いたので試してみた。

配列をforinで実行した場合

Firefox3.0
481ms
IE6.0
3234ms
IE7.0
219ms
Safari3.1
219ms
Opera9.5
234ms

配列を普通のfor文「for (var i = 0; i < a.length; i++)」で実行した場合

Firefox3.0
7ms
IE6.0
32ms
IE7.0
16ms
Safari3.1
16ms
Opera9.5
31ms


この結果でびっくりしたのが、forinで回した場合のIE6.0の遅さ
じゃっかんブラウザも固まりかけていました。

配列に対して以下のように3つしか値が入っていないのに、lengthが1001になる場合にはforinのほうが有効かもしれませんが、そうゆう使い方はあんまり配列ではしないのでやっぱり普通にfor文で回したほうがよさそうですね。

さらにlen=arr.lengthのように一旦lengthを退避すればなお良いということかな。

■関連リンク
JavaScriptの配列をも~っと深く理解する:lengthの不思議な動作 - page2 - builder by ZDNet Japan

Arrayのlengthはいったん変数に格納してからループしたほうが速い

既出な内容ではあるが、一応メモとして残しとく。

配列を走査するときに、配列のlengthを一旦変数に格納したほうが速いんじゃないかという話。
実際試してみた。

コードは以下の感じでどのブラウザでも実行できるようにしました。

配列のlengthを退避せずに実行した場合

Firefox3.0
12ms
IE6.0
63ms
IE7.0
63ms
Safari3.1
31ms
Opera9.5
32ms

配列のlengthを退避して実行した場合

Firefox3.0
7ms
IE6.0
16ms
IE7.0
31ms
Safari3.1
16ms
Opera9.5
16ms


おお~、全然違うみたい。
とはいっても9万回以上ループした場合の結果なので、実際の開発でこれぐらいの差がでるかどうかは微妙ですが、塵も積もれば何たらってやつで意識しておけば処理の重いJavaScriptでもちょっとしたメリットはあるかもしれません。

■関連リンク
JavaScriptの配列をも~っと深く理解する:lengthの不思議な動作 - builder by ZDNet Japan
配列を for で回すときは length を何度も参照すると遅い - gan2 の Ruby 勉強日記

Webサイトの高速化 - styleはheadタグ内に書くと描画が速い

Webサイトの高速化 ルール5 CSSは上に! (Yahoo! developer netoworkより翻訳) | パフォーマンスチューニングblog | インターオフィスより

スタイルシートの読み込みは普通headタグ内で行いますが、ときとして後からHTMLに追記したスタイルがHTMLの下のほうにある場合があります。
(本当はちゃんと別ファイルとして作成しなきゃいけないのですが、直接書かれている場合があったり・・・)

こういったことをしてしまうと、画面の描画に影響を受けるということを以下の記事で知りました。
IEなどはスタイルが読み込み終わるのをじ~と待っていて、Firefoxは待たずにどんどん描画してしまうので、display:noneな要素も一瞬見えてしまうなどの問題があったりするみたいです。



スタイルシートを下のほうに配置すると、IEも含めて多くのブラウザにとって、徐々にページを表示することができなくなります。ブラウザは、スタイルが変更されてページ要素を再描画しないといけなくなるのを避けるために、ページを読み込み終わるまで描画をブロックします。そのため、ユーザは真っ白なページを見続けることになります。Firefoxは描画をブロックしません。そのためスタイルシートをロードし終わった時にページ要素を再描画する場合があります。その結果、the flash of unstyled content problem(スタイル適用前のコンテンツが一瞬見えてしまうこと)といった問題が発生する場合があります。


via: Webサイトの高速化 ルール5 CSSは上に! (Yahoo! developer netoworkより翻訳) | パフォーマンスチューニングblog | インターオフィス


ユーザビリティとして真っ白な画面が何秒か表示されているのは具合が悪いもんです。
たとえば昔、巨大なTableタグでHTMLを囲っているときがありました。
今みたいにdivタグでfloatされるのが流行る前ですね。
Tableタグはその中身がダウンロードし終わらないと描画が開始されないので、ブログとかのテンプレでこの方法を使っているとユーザーは5秒以上何もない画面を見たりしてました。

それとAjax関連で通信をしているあいだ、グルグル回るアニメーションgifとかで「今検索してますよ~」を通知して待っているあいだもユーザーを不安にさせないなんて方法も今となっては主流ですね。

ちょっとした工夫で描画が変わってくるのはなかなか実感がないですが、意識しているだけで全然違うんでしょう!

いやはや勉強になります。

キングボンビーがサイトを侵略する?jQuery Plugin - kingbonbi.js作りました

更新履歴

2008/08/23
- いろいろ調整しながらなので、動かなかったりご迷惑をお掛けいたします。とりあえず落ち着きました。
- ブログパーツ用のコードを変更しました。JSファイルの読み込みではなくアンカータグにしました。

kingbonbi
なんかものが落ちるjQuery Plugin - JDropper作りましたに引き続きオモロ〜なJavaScriptを作ってみました。

なんでキングボンビーを採用したのかよく分からないのですが、お風呂の中でなんか面白いことJavaScriptで出来ないかな〜と考えていたらキングボンビーに行きつきましたw
しかも名付けて「kingbonbi.js」!!
そのままです。

ブログパーツかBookmarkletとして公開いたします。
また今回もソースコードは公開いたしますので、何かの参考になれば幸いです。

続きからご覧ください。

Continue reading

jDropper.jsのブログパーツとBookmarklet

更新履歴

2008/08/23
- ブログパーツ用のコードを変更しました。JSファイルの読み込みではなくアンカータグにしました。

この前リリースしたなんかものが落ちるjQuery Plugin - JDropperのブログパーツとBookmarkletを用意してみました。

単になんかものが落ちるだけのjQuery Pluginですが、いろんなブログ上で実行してみると背景の配色が各々のブログで違うのでなんか面白かったですw

ブログパーツ用のコード

<a href="javascript:(function(){var%20s=document.createElement('scr'+'ipt');s.charset='UTF-8';s.language='javascr'+'ipt';s.type='text/javascr'+'ipt';var%20d=new%20Date;s.src='http://lab.hisasann.com/jdropper/js/bookmarklet.js?u='+escape(document.location.href)+'&d='+d.getMilliseconds();document.body.appendChild(s)})();"><img src='http://lab.hisasann.com/jdropper/img/jdropper2.png' style='border: 0px ;'/></a>

Bookmarklet用のリンク

以下のリンクをブラウザのお気に入りにドラッグしてください
jDropper

ご利用にあたって

本PluginはjQueryを使っておりますので、ブログパーツやBookmarkletを使った場合に画面の挙動がおかしいなどの現象がある場合にはご利用にならないようお願いいたします。

jQueryのheight()やwidth()はOpera9.5に対応していない気がする

jQueryは1.2からheightメソッドやwidthメソッドでdocumentwindowのサイズを取得することができるが、Opera9.5対応がされてないような気がしたのでメモメモ。

heightメソッドやwidthメソッドは本当に便利で以下のようにエレメントの幅や高さを簡単に取得することができる。

これはこれで重宝するメソッドではあるのですが、どうもOpera9.5でwindow(表示されている領域)の幅や高さを取得したときに思ったとおりにならなかった。

で、実際jQueryを見に行ってみた。

jQuery 1342行目

No~~~~~!
Operaの場合(jQuery.browser.opera)にdocument.body[ "client" + name ]で取得している。
このdocument.body[ "client" + name ]はおそらくOpera9.5未満のバージョンで有効なんじゃないかな?
今手元にその環境がないので確かめられないのだが、以下のとおり9.5からは
document.documentElement.clientWidthdocument.documentElement.clientHeightを使うべきだと思う。

Opera 9
標準
document.body.clientWidth
document.body.clientHeight


互換
document.body.clientWidth
document.body.clientHeight


Opera 9.5
標準
document.documentElement.clientWidth
document.documentElement.clientHeight


互換
document.body.clientWidth
document.body.clientHeight


via: ブラウザの表示領域のサイズを取得する方法。 - Enjoy*Study

ということでOperaでうまく取得できないので、自作!

jQueryのメソッドをさらにラップする形にしてみました。
これでいけるっしょ!
でもこれだと今度9.5にしか対応していないから、バージョンごとに分けないといけないのか。
面倒だな〜w

次のjQueryのバージョンで直るのかな?

Safariでは画像のloadが終わっていないとwidth、heightがうまく取得できない

IE6.0、IE7.0、Opera9.5、Firefox3.0ではちゃんと画像の幅や高さが表示されるのに、
Safariでは画像のwidth属性height属性をキチっと指定しないと「0」になってしまう。

今回はjQueryを使ってサンプルを紹介していきます。

たとえば以下の場合

そんなに普段画像の幅や高さを取得したりすることは少ないかもしれないが、
意外とハマるので気をつけたい。


そしてこれを回避するためには以下のように画像のonloadを待つ必要がある。

これでSafariでようやく画像の幅、高さが取得できるが、毎回onloadイベントをbindさせるのも面倒だし、
バインドできないシチュエーションなんかもあるかもしれない。

なので単純にimgタグの中にwidth属性とheight属性を必ず書くようにする。
これでSafariの場合でも問題なく幅、高さを取得できます。

実際のデザインのときはだいたいimgタグのwidth属性とheight属性は書いているけど、
書き忘れ時にこの現象に遭遇するでしょう。
こうゆうのって意外とハマりますよね。

なんかものが落ちるjQuery Plugin - JDropper作りました

更新履歴

2008/08/21
- easingの種類を増やしました
- id:pyangoroさんの指摘で名前を変更しましたw
- id:ぁゃιくない(*~Д~)さんのさんまの名探偵的なゲームだと面白いという意見によりちょいゲーム化
- duration(速度)をパラメータとして渡せるようにしました

jdropper

画像やHTML要素が雨のように降り注いだら面白いな〜と思ってこのjDropperを制作しました。
特にこれを使って何かが出来るわけではないですが、ブログパーツの一種として使っていただけたら幸いです。

続きからご覧ください。

Continue reading

Mac OS X 10.5にMT4をインストールしてみた

Perlの勉強としてPlaggerをおすすめされている方は多いと思いますが、せっかく普段MTを使っているのでローカルにMT4をインストールしてみました。

MT4をダウンロードする

以下のサイトからダウンロードし、解凍しときます。

Six Apart - Movable Type のライセンスと購入について

httpd.confの編集

Mac OS Xには「/Users/[ユーザ名]/Sites/」ディレクトリにhtmlファイルを置くと自動的にhttpでアクセスできるようになります。
まずはWeb共有で公開するためのフォルダでCGIが動くように設定します。

このディレクトリにある自分の名前のconfファイルを編集します。(httpd.confファイルではありません)
編集にあたって事前にコピーしてバックアップしておくことをオススメします。

[ユーザー名].confを開いて、

を以下のように編集します。

これでCGIが動く環境が整いました。

Web共有を有効にする

システム環境設定の「共有」を開きます。
そして以下のように「Web共有」にチェックを入れれば完了です。

51716709

MT4をサイトディレクトリに配置する

解凍したMT4フォルダをFinderからサイトディレクトリに配置しました。

あとは「http://localhost/~[ユーザー名]/mt4/」にアクセスすればMT4のindex.htmlが読み込まれます。
やった〜〜!

■関連リンク
Mac OS X 10.5 ( Leopard ) でCGIを使用する - sbs_tsの日記
の記事を大変参考にさせていただきました。

買った本

Head First JavaScript 頭とからだで覚えるJavaScriptの基本
Michael Morrison
オライリージャパン
売り上げランキング: 1352

いっけん筋肉増強をさせられるんじゃないかと思っちゃうジャケットですが、JavaScriptをイラスト付きで解説しているということで購入。
4200円だからすり切れるまで読みますw

Firefoxプラグインで入力補完が使えるCSSエディタ

Firefoxプラグインで入力補完が使えるCSSエディタ

ちょろっとCSSを書きたい人向けなFirefoxプラグインです。
入力補完機能があるので、「あのプロパティどうゆうスペルだっけかな?」というときに重宝しそうです。

MacのTextMateを使っている人にはまったくもって必要のないプラグインですが、それでもちょろっとCSSには向いていますね。

以下のサイトの「Click here to download and install DiavoloTest 0.6.」というリンクからダウンロードしました。

<Glazblog/>

Event.observeでセットするfunction内のthisについて

例えば以下のようにセットすることは多々あると思うのですが、

注意したいのは「this.id」としている部分。
ここのthisはもちろん"hoge"オブジェクトになっててほしいところなんですが、IEではwindowオブジェクトになってしまいます。
以下のサンプルではalert(this.id)でhogeが表示されてほしいところですが、windowIdが表示されます。

が~~ん!

これはPrototype.jsの中でattachEventを使ってイベントを登録しているのが原因かな~なんて思っています。
まぁIEでイベント登録するときはattachEvent使うしかないのですが・・・

ためしにEvent.observeの部分を自分で書いてみたのですが、やっぱりattachEventの部分が「windowId」になる。

さらっと使っていますが、「Event.element(e).id」を使って自分自身のオブジェクトを取得できるようです。
一応これで解決かと思いきや、まだダメなパターンがありそうです。

クリックされたエレメントの上位エレメントにイベントが登録されている場合

クリックされるアンカータグのひとつ上のエレメントにIDがふられて、そのエレメントにイベントが登録されているパターン。

この場合だとまずIEでthis.idはwindowオブジェクトだし、Event.element(e).idで取れてくるのはアンカータグのIDだし・・・
んもうっ。

結局のところ

なんか嫌だけど、こうなの?w

すんごい初歩的なところで悩んでいますが、jQuery使っているとこのあたりが非常にもどかしい。
というかもっといい方法がありそうだw

JavaScriptでアニメーション(animate)するときに気をつけたいこと

サンプルコードを書いていないんだけど、ちょっと基本的かつ意外とハマる問題かな~と思ったのでメモメモ。
とは言っても2点だけw

スライドするdivタグの中にはoverflow:autoなdivタグは入れないほうがいいかも

このシチュエーションは意外あると思う。
divタグ(div1)の中に複数のdivタグ(div2)が入っていて、外側のdiv1をアニメーションでスライドさせてdiv2の部分を切り替えるシチューエーションの場合、div2がoverflowをautoになっているとFirefoxチラチラする。
他のブラウザではこのチラチラ現象は起きないんだけど、どうしてもFirefoxで起きてしまう。
(IE6.0、IE7.0、Safari3.1、Opera9.5ではチラチラしない)

解決策

これを防ぐにはoverflowをhiddenとかにしてautoじゃない状態にする。

ちなみにjQueryでは、animate関数(3026行目の中でこのチェックをしているがアニメーションするdivタグの中にいるdivタグには適用されないので自分でhiddenにする必要がある。

アニメーションする前にhiddenにして、アニメーションが終わったらautoに戻す感じね。

スライドするときにmarginをマイナスとかにしてスライドするとIE6で重くなる場合がある

jFlowというスライド用のjQueryプラグインではmarginLeftmarginTopを使って対象エレメントの位置をずらしているんだけど、もしかするとIE6.0でめちゃくちゃ重くなる可能性がある。

たとえば画像がたくさん入っているdivタグが何枚もあって、そんなエレメントをmarginを使ってスライドする場合は結構厳しい。IE7.0ではすんなりスライドしてくれるんだけど、IE6.0だけカクカクしちゃう。
本来jQueryのanimateはブラウザ依存しないでキレイにアニメーションしてくれるんだけど、このmarginだけは特別なのかしら?

解決策

position:absoluteで位置をスライドするようにする。
とりあえずこれでIE6.0でもカクカクせずに、本来のサクサク感を出すことができる。

まとめ

全ブラウザで同じ感じでアニメーションさせるのは、たとえjQueryを使っていてもなかなか難しい・・・
日々精進でありますっ!

JavaScriptからfloatを取得するときはちょっとした工夫が必要

要素(エレメント)にfloatさせて左やら右やらに詰めて表示する場合に、スタイルから指定するのではなくJavaScriptから指定する場合は以下のように「styleFloat or cssFloat」というプロパティ名でアクセスする必要がある。

わざわざプロパティ名を分けないといけない理由は、以下のようにブラウザによってプロパティ名が違うから。

IEは'styleFloat',Firefox,Safariは'cssFloat',Operaはどちらも大丈夫です


via: prototype.jsを読み解く:第5回 Prototypeライブラリ(1290~1608行目)|gihyo.jp … 技術評論社

floatなんだからそのままfloatでもいいじゃないっ!プンプン。

ちなみにカレントスタイルの取得方法もブラウザによって違う。
なのでIE、Operaは「ele.currentStyle」を使って、
それ以外は「document.defaultView.getComputedStyle(ele, '') 」を使うように分岐している。

Prototype.jsやjQueryを使っているとこうゆうのはあんまり気がつかないが、独自ライブラリ製作では必須になってくるでしょうね。

■関連リンク
getComputedStyle について調べてたら深みにハマったのでメモ - IT戦記
prototype.jsを読み解く:第5回 Prototypeライブラリ(1290~1608行目)|gihyo.jp … 技術評論社

Seaser2を手軽に試すチュートリアル

前に試したはずなのにそのナレッジが手元になかったのでもう一回入門編を試してみました。

JDKのバージョンは「1.5.0_10」で、Eclipseは「3.2」です。

Seaser2のダウンロード

Seaser2のダウンロードは以下から「S2Container 2.4.26」をダウンロードしました。
Seasar2 - Downloads

Eclipseへのインポート

Eclipseのメニューから
「ファイル」 →「インポート」 →「一般」 →「既存プロジェクトをワークスペースへ」 →「次へ」
を選択していって、「アーカイブファイルの選択」で先ほどダウンロードした「S2.4.26.zip」を選択する。

後は次へでインポート開始!

ここから20分ぐらいかかっちゃいましたw
もっと必要なものだけで遊んでみたかったのですが、Seaser2のjarだけじゃどうせだめだろうと思って20分真剣に待ってみました。
(Springのほうもそうですが、aopalliance.jarが必要だのcommons-logging.jarが必要だとか言われのが面倒なので)

Mainクラスの作成

mainメソッドを持つクラスを作成していきます。

とりあえずこんな感じ。

インターフェースの作成

こんだけ。

インターフェースをインプルしたクラス作成

メッセージをコンソールに表示するだけのクラスです。

diconファイルの作成

ダイコン・・・

少し補足ですが、
①はコンポーネントを手動で登録していくバージョンです。
 複数のクラスをDIコンテナに登録する場合はここにすんごい量の記述が必要になります。
 (後のAOPで定義しているのでコメントアウトしています)

②ここはSpringでいうところのautowireと同じ感じですね。
 正規表現で記述すると自動で登録してくれます。これは便利です。
 (後のAOPで定義しているのでコメントアウトしています)

③ロギング用のインターセプターの定義です。
 これはSeaser2で用意してくれてるインターセプターのひとつのようです。

④traceInterceptorアスペクトをどのクラスにウィービング(織り込む)をするかの定義です。
 呼び出すメソッドにしています。

実行結果

ようやく実行ができる状態になったのでいざっ!
Main.javaのソース上で「右クリック」→「実行」→「Javaアプリケーション」。

おお~、でたでた。
しかもAOPでトレースを出すインターセプターを設定しておいたので、BEGINとENDが出力されています。

まとめ

多分これだけだとSeaser2の利点であるホットデプロイが体感できないですが、初めの一歩としてはいいでしょう。
ただ疑問点が1個出た。
diconファイルの「①個別登録」の部分でnameを指定しているが、これはあれかなセッターインジェクション用なんだろうか。
name=""にしても問題がなかったから、(Service) container.getComponent(Service.class)で取得するときは型で判断してる?

次はS2Strutsだな。

■関連リンク
@IT:The Seasar Projectの全貌を探る(2)
Seasar2 入門

jQueryがIEでもローカルファイルにAjaxでアクセスできる理由

前にJavaScriptでローカルファイルにアクセスする方法でPrototype.jsではIEでローカルファイルにアクセスできないが、jQueryだとうまくいくというエントリーを書きました。

んでいまいちなんでか分からなかったのでjQueryのAjax部分を見てみました。

jQueryで簡単にAjaxコード

まずはjQueryでAjaxを使う方法。

大体こんな感じです。すんごい簡単で相変わらずビックリします!

では内部へ・・・

jquery1.2.6.js(2733行目)

ここにあるonreadystatechange変数に秘密が隠されていました。

普通onreadystatechangeに関数をセットする場合は、IEではActiveXObjectのMicrosoft.XMLHTTPが持つonreadystatechangeにセットすると思いますが、なぜかここでは変数に格納しています。

一方prototype.jsでは

とMicrosoft.XMLHTTPが持つonreadystatechangeにセットしています。
ここが大きく違いますね。

jQueryのほうではonreadystatechangeにセットされた関数をsetIntervalを使って監視しています。
そしてreadyStateが「4 = complete」になったときに処理を開始するようにしているようです。

これによりローカルファイルにもアクセスが可能になっているようです。
でもなんでこれでローカルファイルにアクセスできるんでしょうw
すげっ

上記の部分をふまえてjQueryよりもうちょい簡単にしたバージョンを載せておきます。
参考程度にどうぞ。

jQueryのAjax部分の簡易版

これを見ていてひとつ気になったのが、jQueryではMicrosoft.XMLHTTPを使っていますが、
どうしてMsxml2.XMLHTTPは使っていないのでしょう。
確かMsxml2.XMLHTTPのほうがパフォーマンスが良かったような気が・・・
これも要調査ですな!

■関連リンク
XMLHttpRequest - MDC
The XMLHttpRequest Object
解説 : XMLHttpRequest

bean:writeのfilter属性をfalseにした場合の挙動を追う

Strutsを使ってサニタイジングをした文字列を画面に表示したい場合、
bean:writeタグのfilter属性falseにすれば可能だが、実際にどうゆうクラスが行っているかをちょっと確認してみた。

大体の使いかたは以下の感じだろう。

これで
「<span>hogehoge</span>」
という文字が画面にそのまま出力されるようになる。

これはXSS(クロスサイトスクリプティング)を防ぐ最も重要なことですが、とは言っても
Java側のどのクラスがそれをやっているのかは知らなかった。

今回はstruts-1.3.5を使っています。
では以下じゅんぐり追っていこう!

struts-bean.tld(941行目)

まずはtldファイルの中のwriteを定義している場所を探す。
そうするとタグクラスとしてorg.apache.struts.taglib.bean.WriteTagが指定されていた。

WriteTag.class(246行目)

ここは実際にbean:writeが呼ばれた場合に行う処理の部分。
さぁどこでサニタイジングしているのかな?

filterでif文を分けていたので、ここだ!
TagUtils.getInstance().filter(output)
この部分が怪しい。

TagUtils.class(563行目)

んで、TagUtilsの中に飛ぶとResponseUtilsクラスのfilterメソッドを呼んでいた。

ResponseUtils.class(80行目のメソッドの中)

ありましたw
お決まりの置換処理ですね。
一見強烈に便利なbean:writeですが、蓋を開ければ実にベーシックな処理をしているのが分かります。

普通にWebシステムなんかを作っているとこのbean:writeを多用しますが、
毎回この処理を経由しているわりには速いなと思いました。
まぁそんなもんなんですかね。

bean:write改めて便利ですね~!

■関連リンク
The Ja-Jakarta Site - The Ja-Jakarta Project: サブプロジェクト - Struts翻訳
WriteTag (Apache Struts API Documentation)

Windows環境にPerlをインストールする方法(ActivePerl)

今までWindows環境にPerlをインストールしたことがなかったのでメモメモ。
普段Mac OS Xなので初めから入っているしね。

ActivePerlのダウンロード

以下のサイトからMSI形式のファイルをダウンロードする。
途中名前・メアドの入力が促される。
ActiveState - Online Store, ActiveState ActivePerl Detail

ダウンロードしたバージョンは以下のとおり

ActivePerl 5.10.0.1003

ActivePerlのインストール

次へ次へで完了。
環境変数へperlのパスも自動で追加してくれるみたい。(便利!)

テストプログラムで実行してみる

おお~、ちゃんと「hoge」って出た!


この手のインストールって一癖も二癖もあるんだけど、ActivePerlに関してはあっさり終わりましたとさ。
さぁてPerlの勉強でもしてみようかな。

■関連リンク
ActivePerlのインストール方法 - Windowsでperlを使おう!

jQueryで関数の中の関数でthisを指定してもwindowオブジェクトにならない理由

単純にapply関数やcall関数でthisの対象となるオブジェクトを指定しているからですw

とは言ってもjQueryの内部ではthisを使いまくっていて、ちょっと読むだけだと分からないこともあるので少し具体的にどうやっているのかjQueryの中をのぞいてみましょう!

今回はjquery.jsの1.2.6を使用しています。
また関数やメソッドといった言葉は「関数」に統一しています。後々ややこしくなりそうだったので。

jQuery.fx.each関数の場合

例えばeachという関数では指定したエレメントに合致した全てのエレメントに対して第一引数の関数を実行します。
使い方は以下の感じで引数でfunctionを渡せます。
以後このコードをサンプルとして使用していきます。

そしてこのときのthisは、#hogeで指定したエレメントになるんです。
なのでidプロパティを表示させると「hoge」と表示されます。
ここが重要なポイントですね。普通に独自に作った関数だとwindowオブジェクトになっちゃいますから。


ではjQueryの内部に侵入してみましょう。

jQueryの138行目にeach関数がありますが、その中では他のeach関数を呼んでいるようです。

これはjQueryオブジェクトに直接追加されているeach関数ですね。
先ほどのeach関数はjQuery.fxに所属していますが、今回呼び出しているのはjQueryオブジェクトに所属しています。
なのでまったく別ものの関数になります。
(ちょいややこしいです!)

ではjQuery.eachのほうへ。(724行目

今回はeach関数にfunctionしか渡しておらず、args部分を渡していないので無視しちゃいましょう。
なので一番多きなif文のelseのほうを見ていきます。

lengthは指定したエレメントが1つあるのでundefinedにはなりません。
よってさらにelseのほうになります。

ついに来ました!

「callback.call( value, i, value )」

の部分が
「関数の中の関数内でthisを使用してもwindowオブジェクトにならない理由」
です。
call関数でオブジェクト(指定したエレメント)の縛りをかけているのでthisがwindowオブジェクトではなくエレメントになるのです。

なんだかゴッツイですねw

jQueryで説明をすると結構大変でした。
なのでもうちょい簡略的なクラスを~。

自作クラスでeachっぽいことを表示した場合

う~ん、ついついjQueryっぽく書いてしまいましたが、こんな感じでしょうか。
関数に対して自分はどのオブジェクトに所属しているかを指定するのは一般的なことですが、jQueryではそれを簡単にキレイに使っている部分がポイントだと思います。

まとめ

今回はeach関数を取り上げてみましたが、他にもanimate関数なんかでもこのマジックが使われています。
時間があればそっちも追ってみたいと思います。
(animateのほうはもっとガッツリと重いです!)

Prototype.jsのチートシート(ver1.5、1.6)

すごい今さらな気もしますが、Prototype.jsを使っている方はデスクの脇にでもコピーして置いておくと便利かもしれない。
または電車通勤時の勉強に?

Prototype.js 1.5のチートシート

prototype.js

Prototype 1.5.0 Cheat Sheet - Snook.ca

Prototype.js 1.6のチートシート

perfection kills » Blog Archive » Prototype 1.6.0.2 Cheat Sheet

[via]
phpspot開発日誌

Opera9.5に搭載されているDragonflyが便利な件

Opera9.5に搭載されているDragonflyが便利な件

ボクはもともとFirefoxとSafariをずうっと使っているので、開発でももちろんどっちかを頻繁に使っています。
Firefoxの場合はFirebugは必須ですし、Safariの場合も標準で搭載されている開発ツールを使っています。
どっちもconsole.logが使えるので便利ですしね。

そして最近になってOperaのバージョンが9.5に上がっていたのでいろいろ遊んでいたのですが、標準搭載のDragonfly開発ツールが結構いい感じに仕上がってました。
中身はFirebugと同等なのですが、今回のOperaのUIにとっても合っててサクサクしててこれなら

「Firefox + Firebug」 or 「Opera + Dragonfly」

といった感じで開発を進められそうです。
Webインスペクタはもちろんのこと、HTML階層構造も表示を変えられたりできて見やすくできます。

Opera9.5 Dragonflyのボク的な便利機能

  1. Firebug相当の機能が盛込まれてる
  2. Altデバッガでalt指定していない画像などを一発で探せる
  3. アウトライン機能で画面の構成を確認できる
  4. 目次機能でh1・h2・h3などのタグ構成を一発で把握できる
  5. グリモン不要でuser.jsが使える
  6. Firefox3同等でかなりレンダリング速度が速い
  7. console.log() = opera.postError();
  8. とにかくUIがメタリック調でかっこいいw

メニュー「表示」のスタイルから実行できる機能は以下のとおり。

FirefoxのWeb Developerアドオンを入れれば上記相当の機能は実現できますが、とはいえ初めから入っているのは魅力的。

これでいよいよ全ブラウザ?で開発することが可能な環境が整ってきましたね。
ちょうどFirebug Lite 1.2登場のおかげでブックマークレットからFirebugを呼び出せるようになったし。これでIEも怖くない!

以下からOpera9.5 + Dragonflyをダウンロード可能です。
Opera Dragonfly

■関連リンク
Opera Dragonfly 入門 (Japanese) - Opera Developer Community
プログラマが生産性を上げるためにoperaを使うべき11の理由 - labs blog

IEでposition:absoluteを使った場合margin-topが無視されてしまう

前にIEでfloatを使った場合margin-bottomが無視されてしまうでfloatしたときのmargin-bottomが無視される件を取り上げましたが、今回はfloatとか特に使用していないのですがmargin-topがIE6.0IE7.0で無視される場合がありました。

条件はposition:absoluteなdivタグ(div1)と普通のdivタグ(div2)が並んでいる場合に、div1のほうはdisplay:noneにしておいて、div2にはmargin-topを指定しておきます。
そしてボタンなどからdiv1をdisplay:blockにするとdiv2のmargin-topが無視されてしまうようです。

position:absoluteなんだからdiv2の上にはいないはずだし、いたとしてもdiv2のmargin-topが無視されるのは意味が分からないな~。
ちなみにIEだけでした、他にSafari3.1やOpera9.5、Firefoxなどで試してみましたがこんな現象はなかったです。

display:noneな画像はOperaでPostされない

イメージタグを使ってなんらかのWebサービスに値をPostしたい場合に、そのElementがdisplay:noneだとなぜかOperaだけPostされなかったです。
あんまりdisplay:noneにしなきゃいけないシチュエーションは少ないかもしれませんが、これもまたブラウザの仕様なんですかね。

サンプルHTMLはこんな感じです。

以下Postされるかされないかの一覧です。

IE6.0
Postされる
IE7.0
Postされる
Netscape7.1
Postされる
Safari3.1
Postされる
Firefox3.0
Postされる
Opera9.25
Postされない

ただOperaのバージョンが9.25なので、最新の9.5でどうなっているかは試していませんw

■追記
コメント欄にて教えていただきました。

どうやら9.5から改良が入り読み込むみたいです。

まず前提として、Operaではdisplay:noneな画像(直接指定されていなくても、親のdisplay:noneを継承していれば)は読み込みをしない(リクエストが発生しない)という特徴があります(おそらく表示の高速化のためでしょう)。そのため、以前のバージョンではonloadイベントが発生することもありませんでした。


対して、Opera9.5ではimgにonloadが記述されている場合はdisplayに関わらず読み込みを行うように修正されました。


via: Opera9.2から9.5でのJavaScript周りの変更点 - 0x集積蔵

IE用CSSHackのアンダースコアハックについて

IE6や7での表示がどうしてもうまくいかない場合にはアンダースコアハックを使って、うまいことやる場合がありますが、ちょろっとテスト用のコードを書いたときにハマることがあるのでメモメモ。

アンダースコアハックは以下のようにプロパティ名の前にアンダースコア「_」をつけるのですが、これはあくまでもDoctype宣言がない場合にうまくいく方法です。
これを表示すると100pxのほうが無視され200pxが有効になります。

なので以下のようにDoctype宣言を入れて確認とかをするとまったく、アンダースコアハックが機能しない。
普通Webサイト製作ではDoctype宣言はほぼ必須になっているので、こうなってくるとそもそもアンダースコアハックが使えないのでは?というのがボクの考え。

出来ればハックを使わないほうがかっちょいいんですが、どうしてもIE6や7に適用したい~~~!というシチュエーションでは「* html body」を使うようにしています。

他にもいろんなCSSハックがあるようですが、分からなくなっちゃうので使うのは上記のやつぐらいですね。

■関連リンク
Lucky bag::blog: IE7 を含むモダンブラウザ向けの CSS ハックまとめ

AS3で画面いっぱい(フルスクリーン)で表示させる方法

YouTubeなどを見ていると、画面いっぱいに開くためのボタンがありますが、
どうやっているんだろうと思って調べてみました。

stage.displayStateプロパティの値をfullScreenにするだけだそうです。

ただし

フルスクリーン表示の切り替えは、セキュリティの都合上ユーザーが意図せずに行われるべきではないという事で、必ずマウスイベント中か、キーボードイベント中に記述する必要があります。操作していないときにプロパティを変更しても何も起こりません。


via: FlashゲームPG講座 For AS3.0【Stage クラスについて】

となっているので、ボタンとかを作って試したほうがよいですね。

以下はコンボボックスを使った場合のサンプルコードです。

このとき

とHTMLのほうでフルスクリーンを許可するのをお忘れなく。

■関連リンク
Flashゲーム講座&ASサンプル集【Flash の画面表示について】
FlashゲームPG講座 For AS3.0【Stage クラスについて】
[ActionScript 3.0]フルスクリーン(stage.displayState) | moriBlog

ActionScript(AS3)からJavaScriptを呼ぶ方法(ExternalInterfaceクラス)

以外とハマったのでメモがてらに残しとく。
Flashを作っていくとどうしてもHTMLと連携してみたくなっちゃうのが心情で、じゃあどうやってやるの?というとネットにはそこそこ情報が載っているのですが、何かと難しい。(ボクだけかも)

使ってるツール

Adobe Flash CS3 Professional(Flash 9.0)

新規にFlashを作ってみる

  1. ファイル→新規から「Flashファイル(AS3.0)」を選び新しくflaファイルを作成する
  2. 適当に名前をつけて保存しとく
  3. 1フレーム目を選択しF9ボタンを押す
  4. 出てきたアクションフレームに以下のコードを記載する

この状態で一旦パブリッシュしとく。(Shift + F12)

これでHTMLファイルが作成されるので、今度はHTMLを編集する。

HTMLファイルを編集する

※注意 HTMLを編集した後にまたパブリッシュしちゃうと元に戻っちゃうので注意
 これなんかいい方法ないのかな?

objectタグとembedタグのallowScriptAccessパラメータをalwaysにする。
これをしないとローカルファイルにアクセスするときにエラーが出る。

こうならないように編集した後のHTMLは以下。

でもまだ先ほどと同じエラーは解消されない。

JavaScriptを編集する

IEでは画面がLoadしただんかいでFlashがアクティブにならない現象があるので、
それを回避するためのJavaScriptを容易されている場合がある。
今回使ったFlash CS3ではもれなく、そのJavaScriptがデフォルトで記載されているので
これを消去する。

scriptタグ内にAC_RunActiveContentに関する記述があるので、全部取り除いてみた。

後はFlashからコールしたい関数を容易するだけ!

これだけw

これでHTMLをブラウザで表示した際に「Hello!」と表示されればOK!
AC_RunActiveContentを外さないとうまくエラーが消えないのがハマってしまったが、
これも何か回避方法があるんだろうか・・・

補足

ローカルFlashファイルからローカルHTMLファイルにアクセスする(今回の場合)ときに
警告ダイアログが出る場合がある。
そのダイアログの設定ボタンからAdobeのページに行って、フラッシュのセキュリティを「常に許可」とかにしとくと次回からちゃんとFlashが動作するようだ。

■関連リンク
Adobe - デベロッパーセンター : 外部APIを使用したFlashとJavaScriptの接続

IE6でレイヤーを表示するとプルダウンが前面にきてしまう現象

lightBox系の実装をしている場合、画面全体を覆うレイヤー1枚とダイアログ用のレイヤー1枚を表示することがありますが、
このときに背景にプルダウンがあるとそのプルダウンを1番前面に来てしまう現象がIE6であります。
IE7ではこのバグが解消されていますが、まだまだIE6のシェアは高いのでサービスによってはこのバグを取りのぞかなけらばならない場合があります。

  • プルダウンメニューの上にレイヤーを重ねると、プルダウンが手前に表示されてしまう不具合が修正されていた。
  • via: PXT255; - Internet Explorer 7 ようやくリリース

    方法としては画面にあるすべてのプルダウンを「display:none」にしてやる方法と「iFrameを使う」方法があります。

    display:noneは結構力技でプルダウンの個数に速度が影響されるため、あんまりオススメできません。
    なのでiFrameで画面全体を覆ってしまう方法をご紹介します。

    以下サンプルソースです。
    IE6の場合のみに、iFrameを作成し透過させます。
    これで画面内にあるプルダウンが見えなくなるので、バグを防ぐことができるのです。


    なんかトリッキーですが、これぐらいやらないとlightBox系の実装が不十分になってしまうんですね。
    う~ん、IE6対応・・・果てしなくメンドクサイw

    ちなみにこのコードはjQueryを使ったThickBox 3.1を参考にしています。
    ありがとうございます!

    ■追記
    どうやらhttpsのサイトでこのiFrameの方法を使うとIE6で確認らしきダイアログが表示されてしまうようです。
    なのでプルダウンをdisplay:noneにする方法のほうが確かかもしれません。

    ■さらに追記
    ewbi.develops: IE, IFRAME, and HTTPS
    こちらでiFrameを使ったHTTPSサイト対応が書いてありました。

    src="javascript:false;"

    これを入れると大丈夫みたいです。ボクはまだ確認できてませんw

    RubyでJavaが書けるjRubyをインストールしてみた

    jRubyのダウンロード

    以下よりjRubyをダウンロード。
    jruby-1.1.3をダウンロードしました。
    Index of /jruby

    ちなみにRubyのバージョンは、1.8.6で、JDKのバージョンは1.5.0_10です。

    環境変数の設定

    以下の変数を追加しました。

    JRUBY_HOME
    C:\work\jruby-1.0
    PATH
    %JRUBY_HOME%\bin
    これでコマンドプロンプトから
    jruby -v
    と打ってバージョンが表示されればOKです。
    (一発目はちょっと時間が掛かりました。)

    jirbで遊んでみる

    Rubyにはチョロっとプログラムをチェックしたいときなんかに使う「irb」が搭載されていますが、
    それのjRuby版です。

    コマンドプロンプトから
    「jirb」を入力し、入力待ちになりましたら
    「p "hoge"」
    と打てばhogeが出力されます。

    でもこれだとただのRubyですので、
    「import 'java.lang.System'」
    とJavaのインポート文を入力してから
    「System.out.println('hogehoge')」
    とすればちゃんと文字が出力されるのが確認できます。おお~~~!

    jirbから抜けるには「exit」と入力すればOKです。

    実際にRubyファイルに書いてみる

    以下のようにhoge.rbファイルを作成しました。
    中身で面白い箇所は、System.out.printlnを呼び出しているところですね。


    でさらにimport文を使って名前空間を省略できるようにすると


    なんかRubyとJavaが混在しているので難しいですねw

    まとめ

    じょじょにRubyの人気が出てきて、Ruby on Railsでの開発も小規模ながら進んできていると思います。
    そんなRuby on RailsからJavaのAPIを呼び出したり、他の人が作ったJavaライブラリを使ったり出来るのはとっても面白いと感じました。

    ただ2個の言語が混ざっているので、超エンタープライズなシステムでは厳しいかな?と思いました。
    でもWebサービス開発とかでRailsとJavaAPIのマッシュアップみたいなことができたらなんか楽しそう。
    RailsからJDBCでRDBにアクセス!すっ、すごいっす。

    ■関連記事
    [Think IT] 第2回:JRubyでHello, World! (1/2)
    こちらの記事を大変参考にさせていただきました。

    jQueryで画面の中央に要素を表示する方法

    jQueryで画面の中央に要素を表示する方法 レイヤーを表示する場合なんかに有効な方法ですが、画面の中央にダイアログやボックスを表示する場合 jQueryを使うとかなり簡単に書けました。

    以下のコードはwindowオブジェクトをjQueryの引数に渡してwidthメソッドheightメソッドで取得しています。

    jQueryのwidthメソッド・heightメソッドを使う


    #hogeというのは中央に表示したい要素のidになります。
    animateでアニメーションさせるとちょっぴりかっこよくなりました。

    Firefox3とIE7で確認しましたが、ちゃんと真ん中に来てました!
    これは助かります。

    ちなみに画面全体(スクロールする部分も含む)の幅や高さを取得したい場合は

    とすると取得が可能です。

    jQueryを使わずに自前でやってみる

    クロスブラウザで泣きを見るパターンですが、画面の幅や高さを取得する方法は
    各ブラウザによってさまざまです。
    なのでレイヤー関連を扱う場合には以下のように、クロスブラウザ対応で取得する必要があります。

    う~ん、あんまり見やすいコードではないですが、jQueryを使えない縛りがある場合には
    こんな感じで書く必要がありますね。

    上記コードは
    • Firefox1.5~3
    • IE6.0
    • IE7.0
    • Netscape7.1
    • Opera9
    • Safari3.1

    などなどに対応している感じです。

    ■関連リンク
    ブラウザの表示領域のサイズを取得する方法。 - Enjoy*Study
    を参考にさせていただきました。
    どうもありがとうございます!

    Objectへの分割代入って面白い

    こんなことができるみたい。
    [via] 素人がプログラミングを勉強するブログ

    オブジェクトが持っているプロパティ名と同じ名前のハッシュIDを持つハッシュを作ると、いちいち何行もプロパティを抜き取る処理を書かなくてもよい。
    なので、自作したクラスとかで試してみるとこんな感じになる。

    さらにこう書いて、変数を省略することもできるみたい。

    なかなか興味深いですね。

    ライブラリ製作で使われているレトロなJavaScript関数10個

    Top 10 custom JavaScript functions of all time

    こちらの記事は2005年に書かれたものですが、久々にこういったJavaScript関数を見ると先駆者たちはすごいな~と関心させられます。

    たとえば、

    イベントを追加するaddEventメソッド

    ほんといまさらですが、よくできたメソッドだと思います。
    今では当たり前かもしれませんが、addEventListenerattachEventを使ってIEとIE以外を振り分けているのとか、なんかグッときちゃう。

    function addEvent(elm, evType, fn, useCapture) {
        if (elm.addEventListener) {
            elm.addEventListener(evType, fn, useCapture);
            return true;
        }
        else if (elm.attachEvent) {
            var r = elm.attachEvent('on' + evType, fn);
            return r;
        }
        else {
            elm['on' + evType] = fn;
        }
    }
    

    よくclass名からエレメントを特定しているけど、これってどうやってるの?という場合には以下、

    クラス名から取得できるgetElementsByClassメソッド

    結構レトロですが、HTMLタグが引数に設定されていない場合は全体から特定のclass名を持つエレメントを探していますね。
    う~ん、これはなかなか重そうだ。

    function getElementsByClass(searchClass, node, tag) {
        var classElements =  new Array();
        if (node == null )node = document;
        if (tag == null )tag = '*';
        var els = node.getElementsByTagName(tag);
        var elsLen = els.length;
        var pattern =  new RegExp('(^|\\\\s)' + searchClass + '(\\\\s|$)');
        for (i = 0, j = 0; i < elsLen; i++) {
            if (pattern.test(els[i].className)) {
                classElements[j] = els[i];
                j++;
            }
        }
        return classElements;
    }
    

    prototype.jsやjquery.jsを使っているとあんまり気にしないかもしれませんが、ちょっとのぞくとレトロなからくりだったり、関心させられるからくりだったりするのでたまに振り返るのは悪くないかもしれません。

    これ以外にも面白い関数が紹介されていますので、是非見てみてくださいな。

    Top 10 custom JavaScript functions of all time

    jQueryのanimateメソッドの使い方

    jQueryで作る Ajaxアプリケーション
    jQueryで作る Ajaxアプリケーションを読んでてanimateメソッドについて細かく書かれていたので遊んでみました。
    (本当はjQueryのソースを追ってたのですが、なんか難しくて挫折してたので本当に助かります!)

    前にjQueryのtoggleメソッドって気持ちいいでtoggleメソッドの使い方なんかを紹介しましたが、このメソッドも内部的にanimeteメソッドを呼んでいます。

    toggle : function (fn, fn2) {
        return jQuery.isFunction(fn) && jQuery.isFunction(fn2) ? this._toggle.apply(this, arguments) : fn ? this.animate( {
            height : "toggle", width : "toggle", opacity : "toggle";
        }
        , fn, fn2) : this.each(function () {
            jQuery(this)[jQuery(this).is(":hidden") ? "show" : "hide"]();
        }
        );
    }
    , 

    animeteメソッドのシグネチャー

    animeteメソッドのシグネチャーは

    こんな感じで、

    animate : function (prop, speed, easing, callback)

    いったい何ものかと言うと、

    prop
    CSSプロパティを連想配列でいっきに渡せます
    speed
    名前のとおりアニメーションのスピードです
    easing
    アニメーション方法を指定できます。プラグインなどを使う場合にはここの文字列を変更するみたいです。デフォルトでは"linear"が指定されています
    callback
    アニメーション完了時に呼び出したいコールバック関数を指定できます

    この4つのメソッドを渡すことによっていろいろなアニメーションをさせることができるのです。
    なんか意外と簡単そうです。

    Continue reading

    Operaが持つwindow.operaオブジェクトについて

    prototype.jsを眺めていたら出だしのところでブラウザ判定としてOperaの場合に、「!!window.opera」を書いてあったので試してみた。

    ブラウザがOperaかどうか判定する処理

    if (window.opera) {
        alert("Operaだね" + opera.version());
    }
    else {
        alert("Operaじゃないね");
    }
    

    versionという関数?があってこれにはOperaブラウザのバージョンが入っているみたい。
    ボクの環境ではOpera9.5が入っているので、alertには9.5と表示されました。

    SafariのconsoleオブジェクトといいOperaのoperaオブジェクトといい結構独自実装はあるのねんw

    ふと思ったんだけど、prototype.jsの

    IE : !!(window.attachEvent && !window.opera)

    この部分って!!document.allじゃダメだったのかな?
    IE判定したいんだもんね。
    いや使えない何かがあるんだろうw

    operaオブジェクトが持つメソッドはここにいろいろ書いてあったので参考までに。
    ユーザー JavaScript による制御: 仕様

    imgタグでonloadイベントを使う

    Ajaxianをダラ見してたらimgタグにonload記述があったのでさっそく実験してみたら・・・動いた!

    <img onload="this.style.width = '500px';" src="hogehoge.png" />
    

    全然知らなかったな~。
    一応Firefox3、IE7、Safari3.1で動作検証済みです。

    ■関連リンク
    kawama.jp: [JavaScript]imgタグでonLoad

    Safari3.1でCSSから文字にアウトラインをつける方法

    文字にアウトラインを付けるなら画像として作ってしまうのですが、Safari3.1では簡単にCSSから装飾ができるみたいです。
    このアウトランのCSSプロパティは正式にはCSS3の規格ではないので使うときには注意が必要だ。
    (仮に使うとしたら完全にSafariユーザーに対するエコヒイキになってしまいますねw)

    文字のアウトライン関連のプロパティは、現状ではCSS 3の規格には取り込まれておらず、W3Cに対して提案されている段階のものだ。

    via: 文字のアウトラインを表示する--FirefoxとSafariのCSS対応 - page3 - builder by ZDNet Japan

    アウトラインをつけるCSSの使い方

    div {
    font-size: 64px;
    font-weight: bold;
    color: skyblue;
    -webkit-text-stroke-color: darkblue;
    -webkit-text-stroke-width: 3px;
    text-decoration: underline;
    }
    

    他にも-webkit-text-stroke-colorと-webkit-text-stroke-widthをいっぺんに指定する-webkit-text-strikeや、Safariで色指定する-webkit-text-fill-colorといったプロパティがありますがここでは割愛しています。

    Safari3.1で表示した場合

    Firefox3で表示した場合

    IE7で表示した場合


    おお!Safariだけデコレーションされてます。
    他のブラウザではcolorプロパティの色が優先されているのでまったく別物になっていますね。
    さぁ使う機会はあるでしょうか?

    ■関連リンク
    文字のアウトラインを表示する--FirefoxとSafariのCSS対応 - builder by ZDNet Japan
    Safari 3.1でWebフォントを利用する--SafariのCSS対応 - builder by ZDNet Japan

    Safari3.1に搭載されたClient-side Database storageを試してみた

    ご存知のとおりHTML5の仕様でSelectors APIというものがありまして、これはクライアント側での永続化としてリレーショナルDBを使えるようにするものです。
    これを初めて知ったときは「ええっ!」となりましたが、CookieではなくDBに値を入れておくということがじょじょに可能になりつつあるようです。
    本当にオフラインでも動くサイトが出てきそうですね。

    具体的な話はamachangの記事で話されているのですが、基本的にはJDBC使ってDBにアクセスする雰囲気でいけます。
    (JavaScriptでトランザクションなんてことは想像もしてなかったですが・・・w)


    Database storage簡単な使い方

    openDatabase
    データベース開く
    transaction
    トランザクション張る
    executeSql
    SQLを実行する

    の3つの関数を使って、SQL実行しその結果を取得する!なんてことが出来るみたいです。
    では簡単ですが使い方をコードと一緒に見ていってみましょう!

    openDatabase関数の使い方

    windowオブジェクトにopenDatabaseプロパティがあるかを確認しています。
    あったらそれを使うし、なかったらSafariじゃないね~といった感じです。

    // DB初期設定
    try {
        if (window.openDatabase) {
            db = openDatabase("Test", "1.0");
            if (!db)alert("DB使えないよ!");
        }
        else
            alert("DBないね!");
    }
    catch (err) {
    }
    

    簡単ですね。


    transaction関数の使い方

    引数のtxはSQLTransactionオブジェクト。
    このオブジェクトがトランザクションを持っているので、そこからSQLを実行したりします。

    db.transaction(function (tx) {
        // ここでSQL実行したりします
    }
    );
    


    executeSql関数の使い方

    SQLを実行してくれる関数です。

    第一引数にクエリー文字列。
    第二引数にバインド変数の配列。
    第三引数に結果を取得した際に実行するfunction。

    db.transaction(function (tx) {
        tx.executeSql(query, [], function (result) {
            // 取得できた
        }
        , function (tx, error) {
            // こっちはエラー
        }
        );
    });
    

    おそらくこの関数をもっとも使うことになりそうです。

    Continue reading

    Safariを使って-webkit-box-shadowでシャドウを付ける

    CSS3のbox-shadowプロパティを使うと簡単にドロップシャドウを付けれるみたい。
    画像とかに付けると見栄えもかっこいい感じになるから早く全ブラウザで対応してほしいところです。
    これが導入されればわざわざPhotoshopでドロップシャドウを付ける必要もなくなる?のにね。

    Safari3では-webkit-box-shadowという名前になっているのでちょっと使ってみました。
    以下が簡単なサンプルです。

    <style>
    <!--
    .shadow {
         -webkit-box-shadow : rgba(0, 0, 0, 0.498039)0px5px10px;
        background - color : rgb(255, 240, 70);
        height : 250px;
        width : 250px;
    }
    -->  </style>
    <div class="shadow"></div >

    これをSafari3で表示させると上の画像のようにドロップシャドウがついた状態になります。
    う~ん、かっこいい!

    ■参考リンク
    WebKit HTML 5 SQL Storage Notes Demo
    ボックスにドロップシャドウの効果をつける--Safari 3のCSS対応 - builder by ZDNet Japan

    StrutsでResetを使わずにCheckbox問題を解決する方法

    Strutsを使っていて且つスコープをSessionにしている場合に結構問題になってくるのが、checkboxを外したときのHTTPPostについてだと思う。
    HTTPの仕様でチェックがついていればvalueがPostされ、チェックがついていない場合はうんともすんとも言わない。

    これを解決する方法としてStrutsが用意しているメソッドがresetメソッドだ。
    resetメソッドを使うとActionFormのセッターが動きだす前に初期化することができる。
    もしスコープをRequestにしているなら毎回インスタンスが生成されるので問題はないが、Sessionだとresetメソッドを使ってcheckboxに対応したプロパティを初期化する必要がある。

    resetメソッド

    public void reset(ActionMappingarg0, HttpServletRequestarg1) {
        this.checkboxVal = "false";
    }
    

    でも独自に実装したStrutsや、resetメソッドを呼ぶことができない場合にはこれまたやっかいになる。
    チェックボックスのonclickイベントで別に用意したhiddenに値を格納し、なんとかサーバーサイドで判断することも可能だがこれだと面倒すぎてcheckboxを使いたくなくなるw

    これを簡単に解決してくれるのが、同じActionFormのプロパティを持つhiddenを使う方法だ。

    JSPの書き方

    <html:multibox name="setterCheckForm" property="setterCheckBase.hogehoge">checked</html:multibox>aaa
    <nested:hidden property="setterCheckBase.hogehoge" value="unchecked"/> 

    ここで重要なのがcheckboxやmultiboxは必ずhiddenより前に書くこと。推測だがPostされたときのメッセージボディに並べられた順番にStrutsのセッターが動き出すので、もしhiddenが最初に書いてあるといつまでたってもcheckboxのほうがセットされなくなってしまう。

    たったこれだけでチェックが入っていればcheckedがPostされ、チェックが入っていない場合はuncheckedがPostされる。
    チェックが入った場合にPostされないのをうまく使ったトリックだが、保守性には少しかけるかもしれないのでご用心。

    Firebugが入っているかをJavaScriptから判断する方法

    簡易版FirebugのFirebug Liteのコードを見てて思ったのが、FirefoxでFirebug Liteを埋め込んだページをロードした場合に、ちゃんと既存のほうのFirebugが開いたのでどっかで判断しているじゃないかと思ったら1行目に書いてあったw

    if (("console" in window) || ("firebug" in console)) {
        alert("Firebugが入っています");
    }
    

    初めのif文がまさにそれ!
    alertは自前で付け足したものですが、if文のところはそれでしょう。

    でももしwindowオブジェクトにconsoleがなかった場合に、次の("firebug" in console)でconsoleというオブジェクトが存在しないためにエラーなるかも。
    いろいろ実験した結果ブラウザにごとに条件分けしないといけないかもです。

    続きで実験用のボタンをご用意しています。

    Continue reading

    innerHTMLに値がないとgetElementByIdでnullになるパターン

    onloadやDomContentLoadedを待たずにJavaScript処理をしたい場合は多々あるのですが、例えば以下のようにあるエレメントの下にScriptタグを書いて実行させる場合にinnerHTMLの値が空っぽだとdocument.getElementByIdで取得したときにnullになってしまう現象があった。

    <span id="txt"></span>
    <script type="text/javascript">
    <!--
    alert(document.getElementById("txt"));
    //-->
    </script>
    

    alertはnullと表示される。

    <span id="txt">aiueo</span>
    <script type="text/javascript">
    <!--
    alert(document.getElementById("txt"));
    //-->
    </script>
    

    alertは[object HTMLSpanElement]と表示される。

    divタグでやっても一緒だった。
    divとかspanはあくまでも枠やラベル的なものでしかないからダメなのかな。

    以下のようにbutton要素の場合はinnerHTMLがなくても大丈夫だった。

    <button id="txt"></button>
    <script type="text/javascript">
    <!--
    alert(document.getElementById("txt"));
    //-->
    </script>

    また当然のようですが、onloadを待てばちゃんとエレメントのオブジェクトが取得できる。
    これが出来ないとinnerHTMLに値を挿入できなくなっちゃうしね。

    <script type="text/javascript">  <!--
    function f() {
        alert(document.getElementById("txt").innerHTML);
    }
    //-->
    </script>
    <body onload="f();">
    <span id="txt"></span >
    </body>

    Firefox2でonload前にalert呼ぶとstyleが崩れる

    たとえばこんな感じで「background-color : #888;/*(灰色)*/」背景を指定しておいて、DOM構築が終わる前にalertを呼んじゃうとFirefox2で変な挙動になる。

    <style>
    <!--
    * {
        padding : 0px;
        margin : 0px;
    }
    body {
        background - color : #888;
    }
    -->  </style>
    <script type="text/javascript">
    <!--
    // 多分DOM構築前に呼んでるからかな?
    alert("");
    //-->
    </script>
    

    alertが出る前と出た後で背景が白いが、Alt+Tabとかでいったん違うウィンドウに切り替えてからもう一度Firefox2をアクティブにすると切り替え前にアクティブにしていたウィンドウの枠ぶんだけ灰色になっている。

    IE7やFirefox3ではならなかったので、Firefox2のバグなのかな。
    まぁDOM構築前にalertを呼ぶことはそうそうないからいいや。

    JavaScriptでちょっと面白いコード - 式クロージャ

    素人がプログラミングを勉強するブログさんでちょっと面白い書き方を教わったのでメモメモ。

    このコードは

    var Class2 = function()function()function()alert("b");
    Class2()()();
    

    このコードと同義。

    var Class = function () {
        return function () {
            return function () {
                alert("a");
            }
        }
    }
    Class()()();
    

    呼び出し方がClass()()()とちょっと変わってて面白い。
    クロージャーを使うときに2個まで括弧を付けて書くことはあるけど、3個以上はなかったな。

    追記:
    どうやらFirefox3(JavaScript1.8)から採用された式クロージャという書き方みたい。

    1.7前まではこうかかないといけなかったんですが

    function(x) { return x * x; }

    via: New in JavaScript 1.8 - MDC

    1.8から

    function(x) x * x

    via: New in JavaScript 1.8 - MDC

    このようにreturn文を書かなくても値が返ってくれる。
    だから見たことなかった構文だったんだ!w

    MacOSXのWhiteRoomのようなエディタ「JDarkRoom」

    MacOSXのWhiteRoomのようなエディタ「JDarkRoom」

    MacOSXのWhiteRoomのようなエディタ「JDarkRoom」

    MacOSXのWhiteRoomのようなエディタ「JDarkRoom」

    JDarkRoom

    MacOSXを使っている方なら触ったことがあるかもしれませんが、WhiteRoomというエディターは画面がまるでDOS画面のようにエディターが全画面を覆ってしまうエディター。
    どんな利点があるのかというと作業を集中するということですが、これがまた結構集中できるのです。

    とくに時事的なブログを書いている方にとっては、ブラウザーやらメーラーやらiTunesなんて画面内には必要ない場合が多いのでこういったエディターを使って記事を書くとなかなかなスピードで書けてしまうのです。

    上にあえて3パターンの画像を掲載してみましたが、カスタマイズすると結構かわいげがある自分オリジナルが作れそうです。

    でもWindows版のJDarkRoomがフリーウェアなのにMacOSXのWhiteRoomがシェアウェアなのは一体なぜ~~~!

    Java1.4以上が入ってないとダメなようですが、一応.NET版のリンクも貼っておきますね。

    .NET版のDarkRoomは以下からどうぞ。
    集中力に自信のない人のためのテキストエディタ「Dark Room」:オープンソースを毎日紹介

    [via]
    MOONGIFT

    JavaScriptでローカルファイルにアクセスする方法

    Q2. JavaScriptでローカルファイルを読み/書きたいのですが… A2. Webではセキュリティ制約により絶対無理です。できたら恐ろしいことに…

    via: JavaScriptプログラムメモ|プログラムメモ

    ここに書かれていた内容でJavaScriptからローカルファイルにアクセスは出来ないと書いてあったので、そういえばAjaxで出来たような・・・と。

    単純に「dataだよ」という文字列を持つ「data.html」というローカルファイルにアクセスする方法をprototype.jsとjqueryの場合で試してみました。

    prototype.jsの場合

    document.observe("dom:loaded", function () {
        var r =  new Ajax.Updater("data", "data.html", {
            "method" : "get";
        }
        );
    }
    );
    

    ※IEではうまくいかないみたい。Firefoxで試したらちゃんと取得できました。

    jquery.jsの場合

    $(function () {
        $("#data").load("data.html");
    }
    );
    

    さすがはjquery!
    IEでもFirefoxでもちゃんとローカルファイルにアクセスできました。
    ちょろっとAjaxのコードを書こうとしてもprototype.jsだとAjax用のオプションを設定したりちょっぴり面倒。その点jqueryだと特にオプションを意識しなくてもサラサラと記述できるので簡単ですね。

    CSSでセロハンテープなどの装飾を施す方法

    Web Designer Wallという海外のWebDesignのサイトで紹介されていたCSSのテクニックですが、最近みなさんブログにアップされているようなのでボクも便乗。

    Web Designer Wallを見ていただけると分かるのですが、デザインが美しすぎるんです!
    タイトルヘッダーのぐるぐるした感じがクリエイティブだし、キチっとしたラインを作らずにずらすテクニックがとってもうまいです。

    そこで紹介されていたセロハンテープのテクニックなどは今後使えそうだと思ったのでメモメモ。

    例えば上の画像のようにピンだったりセロハンテープだったりを施したい場合は以下のコードになります。

    CSS

    .photo {
        float : left;
        height : 130px;
        margin : 30px;
        position : relative;
        width : 180px;
    }
    .sample1span {
        background : transparenturl(images / pin.png)no - repeatscroll0 % ;
        display : block;
        height : 21px;
        left : 90px;
        position : absolute;
        top :- 12px;
        width : 28px;
    }
    .sample2span {
        background : transparenturl(images / tape.png)no - repeatscroll0 % ;
        display : block;
        height : 27px;
        left : 50px;
        position : absolute;
        top :- 12px;
        width : 77px;
    }
    .sample3span {
        background : transparenturl(images / paper - clip.png)no - repeatscroll0 % ;
        display : block;
        height : 60px;
        left :- 2px;
        position : absolute;
        top :- 5px;
        width : 30px;
    }
    .sample4span {
        background : transparenturl(images / tape2.png)no - repeatscroll0 % ;
        display : block;
        height : 32px;
        left : 30px;
        position : absolute;
        top :- 13px;
        width : 115px;
    }
    .sample11span {
        background : transparenturl(images / floral - corner.png)no - repeatscroll0 % ;
        display : block;
        height : 72px;
        left :- 15px;
        position : absolute;
        top :- 22px;
        width : 122px;
    }
    .sample14span {
        background : transparenturl(images / glossy - gradient.png)repeatscroll0 % ;
        display : block;
        height : 84px;
        left : 5px;
        position : absolute;
        top : 5px;
        width : 170px;
    }
    

    HTML

    <div class="photosample1">
    	<a href="#">
    		<span></span>
    		<img alt="image" src="images / 9.jpg"/>
    	</a>
    </div>
    <div class="photosample2">
    	<a href="#">
    		<span></span>
    		<img alt="image" src="images / 13.jpg"/>
    	</a>
    </div>
    <div class="photosample3">
    	<a href="#">
    		<span></span>
    		<img alt="image" src="images / 2.jpg"/>
    	</a>
    </div>
    <div class="photosample4">
    	<a href="#">
    		<span></span>
    		<img alt="image" src="images / 9.jpg"/>
    	</a>
    </div>
    <div class="photosample11">
    	<a href="#">
    		<span></span>
    		<img alt="image" src="images / 8.jpg"/>
    	</a>
    </div>
    <div class="photosample14">
    	<a href="#">
    		<span></span>
    		<img alt="image" src="images / 5.jpg"/>
    	</a>
    </div>
    

    外側にいるdivタグにはposition:relative;が指定されているので、その中にいるspanタグのposition:absolute;はdivタグから相対指定になりますね。
    これでちょうどいい場所に装飾用の画像を表示させています。
    意外にも一般的な方法を使っているのですが、かわいらしい画像を使って実装されているともっとトリッキーな方法なんじゃないかと妄想させられますw

    こうなってくるとイラストレーターやPhotoshopを使いこなせるのが最も大切?になってくるのでしょうかね?
    早く覚えねば・・・

    デモは以下のサイトから見ることができます。(楽しいですよ!)
    Firebugで覗いちゃってください。
    Demos | CSS Decorative Gallery

    JavaScriptからVBScriptを呼ぶ方法

    ほぼ使うことはないかと思いますが、ちょっと調べてみました。

    execScriptでVBScriptをコールする

    <script language="JavaScript">
    <!--function msg() {
        execScript("MsgBox('VBscript!')", 'VBScript');
    }
    // -->
    </script>
    <input type="button" value="MsgBox" onclick="msg();">
    
    IE6.0
    使える
    IE7.0
    使える
    Firefox2.0
    使えない
    Safari3.1
    使えない
    Netscape7.1
    使えない
    Opera9.25
    使えない

    JavaScriptからVBScriptの関数をコールする

    <script language="VBScript">
    Function VbConfirm()
        VbConfirm = MsgBox("メッセージ", 257, "メッセージタイトル")
    EndFunction
    </script>
    <script language="JavaScript">
    function test()
    {
        var ret = VbConfirm();
    }
    </script >  < inputtype = "button"name = ""value = "アラート"onclick = "test()"/>
    
    IE6.0
    使える
    IE7.0
    使える
    Firefox2.0
    使えない
    Safari3.1
    使えない
    Netscape7.1
    使えない
    Opera9.25
    使えない

    なんだ基本IEのみなんじゃん。

    でもIE6.0とIE7.0で実行は出来るのだがなぜか「test()」の後にセミコロンを入れるとステートメントエラーが発生してしまう。
    セミコロンを取ればうまくいく・・・う~ん。
    まぁいいやw

    JavaScriptでリフレクション

    意外にも出来るみたい。

    // クラスの定義
    var Hoge = function () {
    }
    Hoge.prototype = {
        alert : function () {
            window.alert("");
        }
    }
    // リフレクション
    var bar = this['Hoge'];
    var methodName = 'alert';
    (new bar())[methodName]();
    

    これでDIコンテナとか作ってみたら面白いかも。
    使うかどうかは分かりませんがw

    ■関連リンク
    リフレクション (情報工学) - Wikipedia

    jQueryのクラス定義はトリッキーでかっこいいよ

    prototype.jsと違ってjQueryはメソッドを呼ぶたびにjQueryオブジェクトを返します。
    なのでオブジェクト汚染がないのがメリットですが、クラスの定義の仕方がちょっぴりトリッキーだったのでメモメモ。

    prototype.jsのクラス定義

    var Class = {
        create : function () {
            //オブジェクトをリターン
            return klass;
        }
    };
    

    これは比較的JavaScripterにとっては安心できるコードですね。
    クラスという変数に連想配列を入れてあたかもクラスのように見せています。


    Element.ClassNames = Class.create();
    Element.ClassNames.prototype = {
    initialize : function (element) {
    this.element = $(element);
    }
    }

    こっちは上で紹介したClass.create()を使ってオブジェクトを取得し、そのprototypeにメソッドを追加していっています。
    こっちのほうがプロトタイプベースな感じが出ててJavaScript~!って感じがします。

    jQuery.jsのクラス定義

    jQueryを見てみると初めに

    (function () {
        /*
        * jQuery 1.2.6 - New Wave Javascript
        *
        * Copyright (c) 2008 John Resig (jquery.com)
        * Dual licensed under the MIT (MIT-LICENSE.txt)
        * and GPL (GPL-LICENSE.txt) licenses.
        *
        * $Date: 2008-05-24 14:22:17 -0400 (Sat, 24 May 2008) $
        * $Rev: 5685 $
        */
    

    という部分がありますが、一見普通のコメントか~と思っていると1行目になんかいる!
    そう、匿名関数(無名関数)ですね。
    つまり、jQuery.jsの全体をこの匿名関数で覆われていて、一番最後の行(3549行目)で実行しています。

    });})
    (); ←ここですね。
    

    なかなかいやらしいですね。

    ではjQuery.jsのコードはかなり長いので比較的コンパクトにまとめてみました。
    以下がそれです。

    (function () {
        var jQuery = window.jQuery = window.$ = function (ele) {
            return new jQuery.fn.init(ele);
        };
        jQuery.fn = {
            //jQuery Instance
             init : function (ele) {
                this.prop = ele;
            }
            , alert : function (x) {
                window.alert(x);
            }
        }
        jQuery.fn.init.prototype = jQuery.fn;
    }
    )();
    

    分かりやすくするためにコードを簡単にしていますが、大体こんな感じでしょう。
    これを実行するには普通にjQueryを使う感じで実行できます。

    $().alert("hogehoge");
    

    初めの$()でjQueryのオブジェクトが返ってくるので、後はメソッド定義されているalertを呼び出せば実行できるという感じです。
    ただこのコードにはjQueryらしいスパイスがふんだんに盛込まれているのでちょっと説明してみましょう。

    Continue reading

    ActionScriptでクロージャを使う方法

    戻り値にFunction型を指定できるので普通にクロージャって概念があるのね。

    package {
        import flash.display.Sprite;
        public class astestextendsSprite {
            public function astest() {
                var func : Function = closure();
                func();
            }
            private function closure() : Function {
                var str : String = "test";
                return function () : void {
                    trace(str);
                }
            }
        }
    }
    

    実行するとコンソールに「test」と出力されます。

    jQueryの再帰呼び出しはとってもトリッキー

    再帰呼び出しは関数内で自分自身を何回か呼ぶことを指しますが、jQueryの再帰呼び出しはちょっぴりオシャレ。

    例えば2340行目あたりでブラウザ毎の処理をしていますが、あるタイミングまでひたすら再帰呼び出しをしています。

    jQuery:1.2.6

    // If IE is used and is not in a frame
    // Continually check to see if the document is ready
    if (jQuery.browser.msie && window == top)(function () {
        if (jQuery.isReady)return;
        try {
            // If IE is used, use the trick by Diego Perini
            // http://javascript.nwbox.com/IEContentLoaded/
            document.documentElement.doScroll("left");
        }
        catch (error) {
            setTimeout(arguments.callee, 0);
            return;
        }
        // and execute any waiting functions
        jQuery.ready();
    }
    )();
    

    一見単にif文があるだけのように見えますが、if文のすぐ右側から無名関数を記述しています。
    そしてその無名関数内で「setTimeout( arguments.callee, 0 );」をしているので自分自身は無名関数になる。
    おお~!これなら再帰呼び出しされるのは無名関数内にとどまるからコードを見ていても理解しやすい。

    以下適当に作ったサンプルコード。
    遠目で見ると関数が存在しないように見えますが、if文の右側から関数が始まっています。

    var num = 0;
    if (num == 0)(function () {
        try {
            num++;
            if (num != 5)throw "hoge hoge";
        }
        catch (error) {
            // numが5になるまで再帰呼び出し
            setTimeout(arguments.callee, 0);
            return;
        }
        // 5
        console.log(num);
        }
    )();
    

    値の監視をとかをするときにこのトリックは使えそうですね。

    UTF-8で保存されたMSゴシックはIE6.0で崩れる

    MSゴシックでギュギュっと同じ幅にされちゃうから崩れるのかな?
    なので基本的にはMSPゴシックを使うようにしています。

    <style>
    <!--
    .small {
        /* これは崩れる */
        font - family : 'MS ゴシック';
        /* これは崩れない */
        /* font-family: 'MS Pゴシック'; */
    }
    -->
    </style>
    <!-- IE6.0で崩れる -->
    <div class="small">
    株式会社TEST<br /> うんたらかんたら </div>

    なぜかIE6.0限定です。

    SafariではCSSクラスの中括弧がないと無効になる

    記述忘れとしてCSSクラスの中括弧を閉じなかった場合に、WinSafari・MacSafariではそのCSSクラスが無効になってしまう。
    まぁ忘れずにちゃんと書けばよいのですが、試しに忘れちゃった場合を想定してみました。

    以下サンプルコード。

    <style>
    <!--
    div#box {
      position : absolute;
        top : 100px;
        left : 100px;
        width : 100px;
        height : 100px;
        border : 1pxsolid#888;
     /* ここに閉じ中括弧がない */
    -->
    </style>
    <div id="box">
    が~~~ん!
    </div >

    div#boxのクラスは閉じ括弧がないようにしています。
    これをSafariで表示した場合にはとくにCSSが効いていない上体で表示されます。

    またWindows版のモダンブラウザの挙動を以下にまとめました。

    IE6.0
    有効
    IE7.0
    有効
    Firefox2
    有効
    Opera9.25
    有効
    Netscape7.1
    有効
    WinSafari
    無効
    MacSafari
    無効

    ちなみに開始中括弧がなくてもダメのようです。

    知ってれば問題なしっ!

    Ruby on Railsの年表

    Ruby on Railsのリリース履歴(日付は日本時間) 2004年7月25日
    2004年12月17日
    2005年12月14日
    2006年3月29日
    2006年8月10日
    2007年1月19日
    2007年11月25日
    2007年12月7日
    2007年12月18日 Rails 0.5.0リリース
    Rails 0.9.0リリース
    Rails 1.0リリース(正式版リリース)
    Rails 1.1.0リリース
    Rails 1.1.6リリース(セキュリティホールへの対応など)
    Rails 1.2.1リリース
    Rails 1.2.6リリース(1.2系の最終バージョン)
    Rails 2.0.0リリース(RESTサポートの強化)
    Rails 2.0.2リリース(本稿執筆時点の最新バージョン)

    via: Strutsの知識を基に、Ruby on Railsを学ぶ方法 − @IT自分戦略研究所

    Javaの年表

    avaの年表
      1996年 1月
    1997年 2月
    1998年12月
    2000年 5月
    2002年 2月
    2004年 9月
    2006年12月 JDK 1.0
    JDK 1.1
    JDK 1.2
    J2SE SDK 1.3
    J2SE SDK 1.4
    J2SE SDK 5.0
    JDK 6

    via: Javaエンジニアにこそ、Rubyの良さが分かる − @IT自分戦略研究所

    クロージャのスコープは関数オブジェクト単位だよ

    closure関数の戻り値の無名関数(method)を実行するとまず無名関数内にiという変数があるか確かめる。
    自分自身にもっていないのでスコープチェーンで上位のclosure関数を見に行きi変数があるのでそれをインクリメントしてアラート。

    closure関数から飛び出た無名関数内でi変数をいつまでも参照しているので、オブジェクトは破棄されない。やった〜。

    そしてclosure関数をもう一度呼び出してクロージャを取得し、同じことを実行するとさっきまで使っていたクロージャとは別のスコープだということが分かる。

    当たり前と言えば当たり前なのだが、関数ごとにCallオブジェクトが作られるので別々のクロージャ空間とも言うべきスコープになる。
    これってActionScriptにもあるのかな?

    function closure(x) {
        var i = x;
        return function test() {
            i++;
            alert(i);
        }
    }
    var method = closure(10);
    //11
    method();
    //12
    method();
    var method2 = closure(20);
    //11
    method2();
    //12
    method2();
    

    window.window.window.windowはwindowオブジェクト

    windowプロパティはWindowオブジェクトの参照先を保持するプロパティなので、windowプロパティ、つまりwindowオブジェクトのwindowプロパティもまたwindowオブジェクトなのである。
    なんか書いてて分かりにくくなってしまったが、以下のコードを見てもらえば一目瞭然だろう。

    console.log(window.window.window.window.window.window.window.window);
    window.window.window.window.window.window.window.window.alert("test");
    

    どんだけやねんっ!w

    IEでliにpadding-bottomを入れたときに色が覆いかぶさる

    IE6.0とIE7.0でしか起こらないのだが、ちょっぴりヘンテコなバグっぽいのでハマってしまったのでメモメモ。

    divタグの中にulタグとliタグが入っていて、そのliにpadding-bottomが掛かっていた場合にliを含めているdivタグの背景色がスクロールしたときにはみ出してしまう。
    あえてスクロールバーを出すために一つdivタグを用意しているが、そこは今回のとは特に関係はありません。
    問題なのはその下にあるclass="navi"で指定しているdivタグだ。

    ダメなパターン

    <style>
    <!--
    * {
    padding: 0px;
    margin: 0px;
    }
    div.navi {
    padding-bottom:15px;
    }
    div.wrap {
    background-color:#ECFBDE;
    }
    .wrap2 {
    padding-bottom:10px;
    }
    -->
    </style>
    <!-- スクロールさせたいため -->
    <div style="margin-top: 800px;">
    </div>
    <div class="navi">
    	<div class="wrap">
    		<ul>
    			<li class="wrap2">あああああ</li>
    			<li class="wrap2">あああああ</li>
    			<li class="wrap2">あああああ</li>
    		</ul>
    	</div>
    </div>
    <div class="navi">
    	<hr>
    </div>
    

    なんとか解決する方法?みたいなものを発見したので以下にメモしておく。

    とりあえずうまくいくパターン

    <style>
    <!--
    * {
    padding: 0px;
    margin: 0px;
    }
    div.navi {
    padding-bottom:15px;
    /* width:800px; */ /* widthを入れるとうまくいく */
    }
    div.wrap {
    background-color:#ECFBDE;
    /* border: 1px solid; */ /* borderを付けるとうまくいく */
    }
    .wrap2 {
    padding-bottom:10px;
    }
    -->
    </style>
    <!-- スクロールさせたいため -->
    <div style="margin-top: 800px;">
    </div>
    <div class="navi">
    	<div class="wrap">
    		<ul>
    			<li class="wrap2">あああああ</li>
    			<li class="wrap2">あああああ</li>
    			<li class="wrap2">あああああ</li>
    		</ul>
    	</div>
    </div>
    <div class="navi">
    	<hr>
    </div>
    

    あんまり正攻法とは言えないが、以下のことを実施すると背景色がはみ出るのが防げた。
    borderをつけるほうはborderを使わないパターンの時には使えないのでwidthが有効だろう。

    • widthを入れるとうまくいく
    • borderを付けるとうまくいく
    • そもそもpadding-bottomを付けなければうまくいく

    なんかこれ以外にもいい方法がありそうだが、今のところ発見できなかった。

    Internet Explorer (Windows) CSSバグリストを見ても見当たらなかったので、今後もハマりそうな予感大!
    クロスブラウザ対応は大変っすね。特にIE!
    なお標準モード、互換モードどちらもでもなりました。なのでDOCTYPE宣言は上記コードには含めていません。

    CSSで画像の一部を使える「CSS Sprites」

    第10回 CSS Spritesでサイトを高速化で紹介されていたCSS Spritesが気になった。
    CSS Spritesとは例えばサイトアクセス時に各々の画像を別にするのではなく、1枚の大きな画像をダウンロードさせて使いたい部分を表示するという方法。

    Mapを使って画像の一部を使うのではなく、background-positionプロパティで同じことを実現しているみたいです。
    こんなこと出来たんですね。

    続きでCSS Spritesを試してみたいと思います。

    Continue reading

    世界をアンダーグラウンドな世界に置換するブックマークレット

    天才を変態に置き換えるブックマークレット - てっく煮ブログこちらで「天才」から「変態」に置換するブックマークレットが紹介されていたので、文字だけ変えて遊んでみた。

    javascript:void(document.body.innerHTML=document.body.innerHTML.replace(/世界/gi,'アンダーグラウンドな世界'))
    

    サイト内に「世界」というキーワードがあった場合に、「アンダーグラウンドな世界」と置換されます。
    すんごいくだらないけど、なんか面白い。
    自分のブログにこのリンク貼っとこうかな。

    Mac OS X LeopardにTomcat6をインストールしてみた

    Tomcatのダウンロード

    以下のサイトからtar.gzのファイルをダウンロードする。
    Apache Tomcat - Apache Tomcat 6 Downloads

    Tomcatのインストール

    まずはダウンロードしたファイルをTomcatをインストールしたい場所に移動します。
    ここでは「/usr/local/tomcat」にしました。

    mkdir /usr/local/tomcat
    sudo mv apache-tomcat6.0.16.tar.gz /usr/local/tomcat
    

    まずはダウンロードしたファイルを展開します。

    cd /usr/local/tomcat
    sudo tar zxvf apache-tomcat6.0.16..tar.gz 
    

    すると「/usr/local/tomcat/apache-tomcat6.0.16」ディレクトリができるので、こいつにシンボリックリンクを貼ります。
    以下のエントリーを参考にしました。
    CreativeStyle - Mac OS X(Leopard)にTomcatをインストール

    sudo ln -s /usr/local/tomcat/apache-tomcat6.0.16/ /usr/local/tomcat/current
    

    こうしておくと「/usr/local/tomcat/current」がapache-tomcat6.0.16と同じ意味になるのでこれは便利。

    JAVA_HOMEを設定

    Tomcatが参照できるようにJAVA_HOMEを環境変数に設定する。

    export 環境変数として変数を設定する 書式 export 変数名[=設定する値]

    via: UNIXコマンドリファレンス
    echo export JAVA_HOME=/Library/Java/Home >> .bash_profile
    

    権限を付与する

    sudo chown -R username:staff apache-tomcat-6.0.16
    sudo chown -R username:staff current
    

    WTPを使ってServerを立ち上げようとしたのですが、上記権限を付与せずに実行したらエラーが出てハマってしまった。
    この権限を付与せずにWTPのServerを作っても「Servers」ディレクトリには何も作成されないので、Eclipse側からエラーが出ていました。

    Tomcatを起動する

    sudo /usr/local/tomcat/current/bin/startup.sh
    

    「http://localhost:8080/」にアクセスするとTomcatのネコが表示されればOKです。

    ApacheはLeopartに初めから入って入っているんだけど、Tomcatは入っていないんですね。
    インストールするのが勉強になったので、OKです!w

    Mac OS X LeopardでPerlのHello Worldしてみた

    30A230C330D730EB - Mac OS X Leopard - 628088534ED569D8

    Mac OS X Leopardには開発環境がめちゃくちゃ整っている。
    以下のAppleの仕様に書いてあるとおり、オープンソース系の言語が標準だからこれは溜まらん。
    アップル - Mac OS X Leopard - 技術仕様

    開発

    • Xcode 3 IDE(Interface Builder 3付属)
    • Instruments
    • Dashcode
    • AppleScript Studio
    • Automator 2
    • Shark
    • GCCコンパイラ&ツールセット(FSF.orgプロジェクト)
    • DTrace(Sunプロジェクト)
    • Java JDK一式(javac、javadoc、ANT、Mavenツールを含む)
    • Apache Webサーバ
    • AppleScript
    • Ruby and the Ruby on Rails frameworks
    • Python
    • Perl
    • PHP
    • SQLite

    via: アップル - Mac OS X Leopard - 技術仕様

    なので今まで勉強していなかったPerlもRubyといっしょに勉強していこうと思う。
    だって環境があるのに使わないのはもったいないですもんね。
    ちょうどTextMateという最高のEditorもあるので合わせて勉強!

    まずはPerlのバージョン

    perl -version

    どうやら5.8.8。

    Perlコードの作成(HelloWorld)

    #! /usr/bin/perl
    
    

    print "こんにちは!¥n";

    これをhello.plとして保存、そして実行。

    perl hello.pl

    こんにちはと表示される。
    よし、まずはHelloWorldをクリアした。
    後は地道に遊んでいこう。

    なおPerlの勉強にはカテゴリ別詳細目次 - サンプルコードによる Perl 入門ここがめちゃくちゃ読みやすい。

    ちなみにTextMateには、PerlMateという機能があって「Command + R」でTextMate上でPerlを実行できる。
    なのでターミナルからいちいち実行しなくてもいいみたい。
    TextMate〜〜。

    hello.pl 2014 PerlMate

    TextMateのBundle(拡張)を簡単に導入する方法

    Validcode ~ Projects - GetBundle

    Railsに最適なテキストエディター「TextMate」を入れてみた
    で紹介したTextMateですが、どうやら入力補完の機能を拡張できるみたいです。

    例えばデフォルトではJavaScriptの入力補完が入っていますが、jQueryやらPrototype.jsの入力補完もしたい〜という人向け。

    他にも様々なBundleがありどれもこれも魅力的です。
    SQLを発行するためのBundleなんてのもありました。

    このBundle(拡張)を簡単にインストールするには、GetBundleというBundleを入れるとぐぐ〜と楽になります。
    以下からダウンロードしてきて、TextMateのBundleディレクトリに投入しちゃってください。
    Validcode ~ Projects - GetBundle

    投入する先は
    「Applications/TestMate.app/SharedSupport/Bundles」
    の中です。

    後はTextMateのBundleからGetBundleを選択するとInstall Bundleがありますので、こいつをクリック。
    Bundleを選ぶ画面になるので、後は好きなのを入れまくり。
    とりあえずjQueryとかJavaScriptで必要になるのをコロコロ入れています。
    ただjQueryの補完がHTMLファイル上でうまくできないので、なんでなのか調査中です。

    Mac OS X LeopardでRailsとMySQL連携で文字化けする場合の対処

    Mac OS X LeopardでRailsで遊べる環境を構築するまでで環境構築までは終わったんですが、次は文字化けに悩まされるハメに・・・

    やっとのことで解決しました!

    Rails側の文字コード設定

    database.yml

    development:
      adapter: mysql
      database: railsTest
      username: root
      password: 19805525
      timeout: 5000
      host: localhost
      encoding: utf8 ←ここです
      socket: /tmp/mysql.sock
    

    application.rb

    class ApplicationController < ActionController::Base
      # Pick a unique cookie name to distinguish our session data from others'
      session :session_key => '_bookTest_session_id'
      before_filter :set_charset
      private
      def set_charset
        headers["Content-Type"] = "text/html; charset=UTF-8"
      end
    end
    

    environment.rb

    1行目に

    $KCODE = "UTF8"
    

    MySQL側の文字コード設定

    ■文字コードを設定する

    /etc/my.cnf を編集する。

    [client]
    default-character-set=utf8

    [mysqld]
    default-character-set = utf8
    skip-character-set-client-handshake
    character-set-server = utf8
    collation-server = utf8_general_ci
    init-connect = SET NAMES utf8

    via: MySQL 文字化けを防ぐ、文字コードの確認と設定 | 渋谷生活

    ボクは/etc/my.cnfがなかったので以下の手順を踏んだ。

    ■/etc/my.cnfが無いとき

    インストールしたMySQLの中のサンプルをコピーする。

    # cp /usr/local/mysql/support-files/my-medium.cnf /etc/my.cnf

     再起動して有効になる。

    via: MySQL 文字化けを防ぐ、文字コードの確認と設定 | 渋谷生活

    この状態で

    sudo /usr/local/mysql/bin/mysql -u root -p railsTest

    でMySQLにログインし、
    mysql > status
    で以下が表示されるようになる。

    30BF30FC30DF30CA30EB 2014 mysql 2014 80�4

    また、
    mysql > show variables like 'char%';
    で以下のようにUTF-8だらけになればよい。

    30BF30FC30DF30CA30EB 2014 mysql 2014 80�4


    実はDatabaseを作成するときの文字コード指定を間違えていっこうに
    db characterset : latin1
    になったままになってハマってしまった。

    これだと上記の手順をすべて踏んでも文字化けが解消されなかった。
    なので、ちゃんとカラムを作成するときも以下のように文字コードを指定する必要がある。

    localhost / localhost / railsTest / books | phpMyAdmin 2.11.6
    あとRailsなのでidカラムにはオートインクリメントを付けること。
    これもさっきすごいハマってしまった。

    またmy.cnfのパーミッションは気をつけないと永遠にハマる可能性がある。
    ボクは初め問答無用で
    chmod 777 /etc/my.cnf
    ってしてたんだけど、これだとMySQLを実行した際にignoredって表示されて無視されてしまった。

    以下の記事で解決した。


    chown mysql:mysql my.cnf

    chmod 600 my.cnf


    が正解です。my.cnf は

    mysqld_safe が 動作する際に mysqlユーザーのみ参照できればいいわけで。mysqlユーザーがオーナーであれば 600 でいいわけです。そうすれば、world-writable にならずに済みます。


    via: Eriane ver 0.6.1 » 忙しい・・・

    本日はハマりまくりな1日でした〜。
    疲れた・・・w

    ■参考リンク
    sunadaaの日記 : my.cnfを無視させないようにする - livedoor Blog(ブログ)
    文字化け対策のためのあれこれ | Katawara.*
    MySQL 文字化けを防ぐ、文字コードの確認と設定 | 渋谷生活

    Mac OS X LeopardでRailsで遊べる環境を構築するまで

    Mac OS X Leopardにはなんと初めからRuby On Railsが導入されているみたい。
    Rails on OS X !? - Ruby on Rails、Mac OS X Leopardに搭載へ | エンタープライズ | マイコミジャーナル

    せっかくなんでとりあえずRailsが書ける環境まで構築してみた。
    まだMacの操作にも慣れていないのでかな〜りハマりながらになってしまったが、とりあえずできたような気がする。

    RailsはやらないけどRubyを書いてみたいって人にとってもすばらしい環境ですね。
    試しにターミナルで

    ruby -v

    と入力するとRubyのバージョンが表示される。Macで開発をしたことがないけど、これからガリガリ書いていきたい。

    ではMac OS X LeopardでRailsを開発するためのツールをインストールしてみる。


    Aptanaのインストール

    Download Aptana Studio 1.1 | Aptana
    ここからAptanaをダウンロードしてインストール。

    AptanaはすぐれたEclipseベースのIDEで、ボクはJavaScriptやHTMLの作成でよく使っていました。
    そのAptanaにRails開発環境のRadRailsプラグインをインストールすることによって、Rails仕様にする感じです。

    RadRailsのインストール

    Aptanaを立ち上げて最初の画面のRadRailsインストールボタンをクリック。
    aptana.tv

    後は適当に進んでください。

    ■参考リンク
    aptana.tv

    RadRailsの設定

    RailsのPathを指定する必要があるので、
    「Window」→「Preferences」→「Rails」
    を開いて「/usr/bin/rails」と入力する。

    Preferences

    もしPathが怪しい場合は、ターミナルで
    「which rails」
    と入力してrailsのPathを表示させてみてください。

    Railsプロジェクトの作成

    「File」→「New」→「Rails Project」からRailsプロジェクトを作成する。
    これだけでいいみたい。またターミナルから「rails test」のように実行しても同じ感じに雛形コードを自動で生成してくれます。

    たったこれだけでRailsの基本となるコードが生成されサーバーも起動しているので試しにSafariなどで、http://127.0.0.1:3000/と入力すると
    「Welcome to Aptana RadRails」と表示された!!
    おお〜。なんかすごい。

    Aptana RadRails

    起動しているサーバーはRuby標準添付のWEBrickというもので、とりあえずサクッとRailsで遊んでみたい場合にはこれでよいみたい。
    これ以外にもMongrelという起動が高速なサーバーもあるがこれはダウンロードしてこないといけないっぽいから今はとりあえずWEBrickで遊んでみる。

    MySQLのインストール

    以下を見てインストールした。
    MacOSXでサーバー稼業 : Mac OS XにMySQLをインストールしよう

    MySQLをインストールしたら以下のコマンドを打つとMySQLが起動するみたいなんだけど、

    「/Library/StartupItems/MySQLCOM/MySQLCOM start」

    この後に

    「/usr/local/mysql/bin/mysql -u root」

    と打っても
    「ERROR 2002: Can't connect to local MySQL server through socket '/private/tmp/mysql.sock' (2)」
    と表示されてMySQLが立ち上がっていない感じになってしまった。
    う〜ん、何がいけないのか・・・

    ちなみにMySQLのdmgを開いたときにMySQL.prefPaneというファイルがあるのでこれをインストールしておくとわざわざターミナルからMySQLを起動しなくてもよくなる。
    今回はこれで逃げてみよう。

    mysql-5.1.24-rc-osx10.5-x86

    ■参考リンク
    素晴らしき哉、人生!: Mac OS 10.5にMySQLインストール

    phpMyAdminをインストール

    基本的なことは以下を見てインストールした。
    MacOSXでサーバー稼業 : Mac OS XにphpMyAdminをインストールしよう

    ローカルのWebServerにアクセスするためにはシステム環境設定の「共有」からWebServerを有効にする必要があるよう。
    MacOSXでサーバー稼業 : 自分のMacでホームページを公開しよう
    これをやらないで「http://localhost/」にアクセスしてたんだけど、いっこうに表示されないから少しハマった。

    さらに
    「http://localhost/phpmyadmin」
    にアクセスしてもPHPのソースコードが画面に表示されてしまったので、PHPを有効にする必要があるようだ。

    以下にその説明が書いてあります。やっぱり有効にする必要があった〜!
    MacFeeling » Blog Archive » LeopardでPHP
    「/etc/apache2/httpd.conf」→「#LoadModule php5_module libexec/apache2/libphp5.so」
    この行のコメントを外す必要があります。

    これでアクセスしてもまだエラーが表示されてしまう・・・
    どうやらphp.iniというファイルが必要なよう。
    以下のコマンドでpho.ini.defaultからコピーを作成し、ちょびっと編集。

    sudo cp /etc/php.ini.default /etc/php.ini

    "mysql.default_socket ="というところを探して次のように変更。

    mysql.default_socket = /tmp/mysql.sock
    再起動。

    via: voice over the field: Mac OS X 10.4.4でphpとMySQLの問題発生

    phpMyAdminを入れるのに一番苦労してしまった。
    手作業で値の変更するあたりがまだまだ敷居の高さが残ってるのかな。Leopardの次バージョンで全部セットしてくれたら楽なのにな〜。

    localhost / localhost | phpMyAdmin 2.11.6

    やっとこれでRailsで遊べる環境が整った。
    次でちょこちょこコードを書いていこう。

    IEとFirefoxでテキストボックス上でのEnterの挙動について

    テキストボックス上にカーソルがある場合にEnterキーを押すとSubmit