jQuery hashchange eventが素晴らし過ぎた。

 Ben Alman » jQuery hashchange event

 毎度毎度この手の記事の書き出しで書いておりますが、このページをブラウザで見るとAjaxで記事のデータを取ってきて云々。この場合、ページの遷移が発生しなかったり、通信量が少なくて済むなど利点も多いのですけど、欠点も少なくはないです。
 中でも大きいのは各検索エンジンさんがインデックスしてくれない事で、これはほとんどのbotさんがJavaScriptに対応してませんし、普通のアクセスで送られてくるデータに記事の内容が含まれていないので仕方がありません。

 この件に関してはGoogleさんが対応を表明しておりまして、若干面倒くさい仕組みを用意しなければなりませんが一応対応は可能です。詳しくは、Getting Started - Making AJAX Applications Crawlable - Google Codeを参照して頂きたいですけども、「Ajaxで使うhrefを#!スタートにしておいてくれたらこっちで勝手に読み替えて再リクエストするからその時ちゃんとデータを投げてくれ」と提案しています。どうして再リクエストが必要かと申しますと、そのままのURLですと仕様上#以下の部分はサーバまで届かないからです。http://reiare.net/blog/#!spamというURLへブラウザからアクセスしたとして、サーバが受け取るリクエストは普通にhttp://reiare.net/blog/までです、後ろに何か付いていてもそれを知る事はできません。
 当ページではこれには暫定的に適当に対応しています。というのも昔の静的なページも活きているので、Google botさんが再リクエストを投げてきたら該当する旧ページへリダイレクトすればいいかと思ったからです。実際にログを追っかけてみましたが、ちゃんとリダイレクト先のデータを取得してくれている感じでした。インデックスしてくれているのかどうかは知らないけど。

 もう一つ大きめなのはブラウザのbackやforwardが使えない事。Ajaxは後付けの技術でありますが、そのそもページを遷移させない為に産まれたものですから相性がいいわけありません。いろいろページ内で移動したりだとか表示内容を変えたりだとかした後にbackボタンを押すと、何も変わらなかったり、もの凄く前の段階に戻されてしまう事が起こりえます、基本的に使えないんです。この辺り、Gmailなどを使っている方とかだとわりとすんなり受け入れられると思うのですけど、不便と言えば不便ですよね。それに戻るためのリンクの管理も大変です。や、ちゃんと管理するべきですが。
 もちろんこんな事は皆さんわかっていて、それらをどう解決するかという試みがなされてきました。最終的にwindow.onhashchangeイベントを実装するという流れになっているようですが、これまでに世に出てしまったブラウザやら対応していないブラウザやらにはどうしようもありません。時間が解決するとはいえ何とももどかしい、待ちきれない。
 という事で、それらすらも解決し、Ajax遷移時にもブラウザのback、forwardボタンを有効にする為に存在するのが件のライブラリです。この手のライブラリは他にもいくつかあって前々から物色していましたが、今回使ったjQuery hashchange eventはかなりお手軽で素晴らしいと思います。「こんなんだったらもっと早くにAjax化しといたらよかった」と思いましたよ、正直なところ。

 jQuery hashchange eventはその名の通りjQuery専用のライブラリでありますから、ボクら大好きみんな大好きjQueryが必須です。jQueryを読み込んだ後にこのライブラリを読み込みましょう。そうすると、windowオブジェクトにhashchangeというイベントが追加されます。このイベントはブラウザのURL欄が変更される事で発動されるイベントです。実は、これ、IE6とか7とかで実装するのは面倒なんです。
 イベントが追加されたので、今度はこのイベントで行われる処理を登録すれば、あら素晴らしい、backやforwardボタンを押す度に(正確にはURL欄が変わる度に)登録した処理が実行されます。


$(function() {
    $(window).hashchange(function() {
        if (location.hash) {
            path = location.hash.split('#!', 2)[1];
        }
        /* 取り出したpathをもとにごにょごにょする処理 */
    });
});

 私がやっている実装例。hashchangeイベントが発生したら、#!以下の部分だけ取り出してそれに応じたAjax処理を適用させてます。取り出し方はもっといい方法があると思います。あったら教えろ。

 この手のライブラリのいいところは、URL欄が変更されるとイベントが発生するので、aタグのhrefに#!hogeと書いておけば特に個別にclickイベントなどを登録しなくてもいいところです。導入する前は、


$.each(box.find('a[href^="#!"]'), function() {
    var href = $(this).attr('href');
    $(this).click(function() {
        /* hrefをもとにごにょごにょする処理 */
    });
});

 とかして取り出してイベントを貼ったり、個別にイベントを登録したりしてました。こういうのが簡単にできるのもjQueryのいいところですが、やらなくて済むならやらない方がいい、いいに決まってる。後は上手い事キャッシュしてくれて云々とかなると最高だなぁ。

 jQuery hashchange event、本当におすすめです。多分これがスタンダードになるんじゃないかと思うよ。