Shadowbox.jsをAjax.Updaterと併用する
posted at 2009-10-29  [ ]

Lightbox系のライブラリとして任意のJavaScriptライブラリを使ってもOKなShadowbox.js。
非常に便利でおすすめ。私はprototype.jsをよく使うのでそれと併せています。jQuery対応のものばかりで肩身が狭いですが。

Shadowbox.jsの仕様として、下記のようにheadタグ内のscriptタグで初期化する必要があります。

//日本語表示、画像とHTMLをレンダリング対象とする
Shadowbox.init({language : "ja", player: ["img", "html"]});

このためAjax.Updaterなどで部分的に反映された要素はShadowbox.jsのイベントハンドラ登録が行われていない状態です。

そこで、下記の要領でAjax.Updaterを使用後に再度イベントハンドラ登録を行うと要素の更新後もShadowbox.jsを利用できます。

私の場合はForm.EventObserverと併用しているので、その中でcallしているAjax.Updater内に記述しています。

new Ajax.Updater(id,
	url,
	{
		asynchronous:true,
		evalScripts:true,
		onComplete:function(request){
			//その他の処理
			//最後にイベントハンドラの登録をし直す
			Shadowbox.setup();
		},
		onLoading:function(request){
			//その他の処理
			//現在のイベントハンドラをすべてクリア
			Shadowbox.clearCache();
		},
		parameters:value
	})

prototype.js以外のライブラリを使用している場合も、同様にonCompleteやonLoadingに相当するイベントにフックさせれば大丈夫だと思います。

参考:

Shadowbox.js API

追記 2010.01.04

IE6, IE7の場合、Shadowbox.clearCache()を呼ばず、Shadowbox.setup()のみ呼び出すと
正常に動きます。原因はソースを追ってみないとわかりませんが、とりあえず。

また、Shadowbox.setup()の呼び出しタイミングはCGIから返されるHTMLの末尾でscriptタグ内に記述した方が良いです。
DOMのロードとJavaScript実行のタイミングを調整するためです。

IE7でAjaxのその後
posted at 2009-06-27  [ ]

前回のエントリでIE7でAjaxリクエストの挙動がローカルとリモートで異なる件に触れた。

で、その後の調査結果。
IE7でJavaScriptを含んだプログラムを動かすと、ActiveXコントロールを含んでいるけど大丈夫?というポップアップがブラウザ上で表示される。動いてくれないと困るので、「はい」と答える。これが落とし穴。

この時点でActiveXObjectを使って動く前提とブラウザは思いこんでしまう模様。にも関わらず、XMLHttpRequest判定を前に持ってきているので、そっちでリクエストを投げようとするのが不整合の原因のようだ。

そう、つまりリモートにコンテンツを配置した場合はXMLHttpRequestで扱うとブラウザが思ってくれるので、エラーはでなくなるということだろう。うん、やっぱりXMLHttpRequestに統一してくれとして言えない。

ここからは最近なんとなく思うこと。Ajaxってもう、終わりな気がする。というかHTMLで何でも表現するのはいい加減限界だし、DojoやExt.jsのようなリッチUIを用意するのもブラウザ互換吸収とかで苦労するし、無理がきていると感じる。
なのでUI部分をFlashにという流れが今は主流なのだけど、コントロールの出来でいったらSilverlightのが上だろと思うので、棲み分けを作る側が理解して使い分けるのが正解なんだという当たり障りのない結論に落ち着いた。

とりあえず、業務アプリのUIはSilverlightでいきたい。今はまだFlashかなと思う。後々の浸透度次第か。

IE7でローカルからXMLHttpRequestを使うとエラー?
posted at 2009-06-19  [ ]

ActiveXObjectの判定タイミングは前か後か?

とある案件でここと同じであろう現象に遭遇。
IE7からXMLHttpRequestとActiveXObject両方に対応するようになっており、ActiveXObjectの判定は後ろに持っていくべきと言われている。

が、実際のところローカルで実行するとXMLHttpRequestの判定は通るけれども、GETリクエストを投げたところで「アクセスが拒否されました」というエラーが。これはバグと言いたい。

で、結局ActiveXObjectの判定を前にもってくることで解決。腑に落ちない。


        if (window.ActiveXObject) {
            req = new ActiveXObject("Microsoft.XMLHTTP");
            if (req) {
                req.open("GET", url, false);
                req.send();
            }
        } else if (window.XMLHttpRequest) {
            req = new XMLHttpRequest();
            req.open("GET", url, false);
            req.send(null);
        }

ちょっとしたテストをすると、XMLHttpRequestでもActiveXObjectでもtrueとIE7はなる。うーん、善し悪しだこれは。
そうじゃない、ちゃんと仕様を統一してください。
ちなみに、上記の修正を行う前にはFirefoxとChromeは問題なし。IE7とSafariはNG。

やはりいらない子なのか。

とある案件のクライアントは、それまでIE6を使用していたことを考慮すると、IE7の使用率が増えたことでこういった不具合が起きている可能性があるかもしれない。この案件のリリース時はIE7対応しないという契約だったので、よくよく考えてみればこれって、有償にしていいんじゃないか?

冗談はさておき、ブラウザのバグとか仕様解釈の違いをこれだけシェアの大きいソフトウェアで製作者に押しつけたままというのは不満。だけど、それもプログラマの仕事という事実なのは否定できない。

jQueryベースのフォーム入力チェックを実装中
posted at 2009-04-23  [ ]

CSS-Nite Aomoriで5分プレゼンを行うので、その準備中。
それと並行して、自分のサイトをWordPressベースで作ってみた。というか、テーマとして作るという宿題がほったらかしだったという。

で、RubyでYAML形式の定義を元にFormを自動生成したくて、ちまちま書いているのだけど、せっかくだしvalidationはjQueryで作ってみることにした。巷にあふれているものではあるけど、自分の勉強がてらだ。

jQuery自体はバージョンいくつの頃だろう・・・だいぶ前に、prototype.jsとjQueryどちらをベースにしていくか?というテーマがプロジェクト内であって、jQueryの挙動が気に入らず、prototype.jsでいくことに。Railsもprototype.jsが前提なんだけど、あまりにjQueryの名前を聞くようになったし、今だと良くなってるのかもね?と思って使ってみた。バージョンは1.3.2。

 確かにCSSセレクタを使ってDOMにアクセスできるのは快適だし、直感的に書けるコードも多いのだけど、ちょっとHTMLやセレクタが複雑になってくると、思うように要素がとれなかったり、Arrayで値が返ってくるのかjQueryオブジェクトが返ってくるのかがまちまちだったりと、複雑なことやろうとすればするほど、DOM直接いじってる方が楽だな・・・とか思ってしまう。正しい使い方ができてないのだろうか?

$の挙動からいけば、やはりprototype.jsが自分には合っているようだ。というか、まずブラウザ側の挙動を統一してほしい。それに尽きる。挙動の違いを吸収してほしくて、javascriptフレームワーク使っているようなもんだし。今更すぎる内容だけど、改めて使ってみても、やはり思うことは同じだったりする。

となると、棲み分けなのだろうという結論。すでに固定のHTMLがあって、それに対して簡易的なエフェクトやDOM操作を行うなら、jQueryは非常に効率的だと思う。逆に何らかのデータフォーマットやHTTPレスポンスを元にHTML生成したりと、動的な実装をしたいのであればprototype.jsかなと思う。

エフェクトやGUIなどオールインワンのライブラリを求めるなら、Ext.jsかDojoあたりなのだろうか。思い立つことがあれば、今度はそっち側を試してみようと思う。