feedbringer 使うのやめた、とか言っておきながら、feedbringer remix ネタ。別に feedbringer じゃなくても良かったのですが、 ONJava.com: AJAX: How to Handle Bookmarks and Back Buttons を見てたら実験したくなったのと、そういや feedbringer 使うのやめた理由のひとつは、「戻る」「進む」ボタンが使えないからだったなぁ、ということを思い出したので、上記 URL にあるテクニックを feedbringer に適用してみることにした。
いつものごとく、greasemonkey で remix です。 feedbringer_enable_back_and_forth.user.js
実験ということもあり、自分のスキル不足もあってかなりいいかげんなスクリプトですが、簡単に解説を。
// feedbringer_enable_back_and_forth.user.js から抜粋 var js = document.createElement("script"); js.language = "javascript"; js.src = "http://mizzy.org/js/dhtmlHistory.js"; document.body.appendChild(js);
まずこの部分では、上記 ONJava.com サイトで紹介されている、 Really Simply History framework のdhtmlHistory.js を読み込んでいます。
// dhtmlHistory.js から抜粋 dhtmlHistory.initialize(); dhtmlHistory.addListener(historyChange); function historyChange(newLocation, historyData) { $('main').innerHTML = historyData; }
dhtmlHistory.js の最後に、上の6行を追加しています。本来であればユーザスクリプト側に書くべきなんでしょうが、dhtmlHistory.js を読み込み終わってから実行しないエラーとなるため、面倒なのでこっちに書いちゃいました。読み込み完了してから実行する方法がよくわからんし。
ここは dhtmlHistorty オブジェクトの初期化処理ですね。 dhtmlHisotry.addListener が重要なとこで、「戻る」「進む」ボタンを押した時に、どういった処理を実行するのか定義します。ここでやっていることは、後ほど出てくる dhtmlHistory.add によって記録された historyData を、 id が main であるコンテナに書き戻す、ということをやっています。
// feedbringer_enable_back_and_forth.user.js から抜粋 Ajax.Updater.prototype.extend(Ajax.Request.prototype).extend({ ... updateContent: function() { ... if (receiver) { if (this.options.insertion) { new this.options.insertion(receiver, response); } else { receiver.innerHTML = response; var date = new Date(); dhtmlHistory.add('key' + date.getTime() , response); } } ...
ユーザスクリプトで prototype.js の Ajax.Updater を上書きしています。太字の部分を追加しただけですね。xhtmlHttpRequest のロードが完了した時点で、dhtmlHistory.add を実行して、 location.hash の値と、それにひもづくデータを historyStorage オブジェクトに格納、でもって location.hash をここで指定された値に書き換える、ということをやってます。
スクリプトの解説は以上です。これで「戻る」「進む」ボタンを押すと、最初の方に出てきた dhtmlHistory.addListener で指定された historyChange が実行されて、変更された location.hash にひもづく historyData を historyStorage オブジェクトから引っ張り出して、id が main であるコンテナに書き戻す、という具合になります。
今回の例では id=main コンテナ決めうちで書き換えしてますが、 dhtmlHistory.add で格納できる historyData は、 文字列だけじゃなくオブジェクトも指定できるので、 やろうと思えばもっと複雑なこともできますね。
上記 ONJava.com サイトによると、Backbase や Dojo なんかは、こういったヒストリフレームワークが実装されているようです。prototype.js にも実装してほしいっすね。