« publish/subscribe | トップページ | 配列 »

2007年3月24日 (土)

ブラウザのバックボタン/履歴への対応

バック/フォワードボタンへの対応

Ajaxによりデータを取得して画面の一部を書き換えた場合、ブラウザのバックボタンを押しても画面の一部の書き換えを元に戻すことはできない。間違ってバックボタンを押すと、これまでの操作内容は失われてしまう。

画面の一部を書き換えただけでは、ブラウザの履歴(history)、URLを更新しないためである。

dojo.undo.browser を使うことで、Ajaxアプリケーションにおいてもブラウザのバック/フォワードボタンを利用することができるようになる。dojo.undo.browserでは、バック/フォワードボタンの通知を受けて動作するオブジェクト/関数を指定することで、ブラウザのバック/フォワードボタンに対応できるようになる。

dojo.undo.browserを利用するには、まず、djConfigで、preventBackButtonFix: falseを指定する。これにより隠れたiframeが追加される。

次に、dojo.require("dojo.undo.browser"); を指定し、dojo.undo.browser.setInitialState(state)により初期状態を設定する。以降は、ブラウザの履歴に追加するタイミングで、dojo.undo.browser.addToHistory(state)を呼び出す。ここで、stateオブジェクトには、バック/フォワードボタンが押されたときに呼ばれるメソッドを指定する。

バックボタンの通知を受けるには、stateオブジェクトに、back(), backButton(), handle(type)のいずれかのメソッドを定義する。typeには、"forward"または"back"が指定される。

フォワードボタンの通知を受けるには、forward(), forwardButton() or handle(type)のメソッドいずれかを定義する。

簡単なstateオブジェクトの例をあげる。

var state = {
back: function() { alert("Back was clicked!"); },
forward: function() { alert("Forward was clicked!"); }
};

dojo.io.bindを使って、画面を書き換えているのであれば、dojo.io.bindを呼び出すタイミングで、その情報をstateオブジェクトに入れることで、バックボタンが押されたときに、状態を元に戻すような動作を行うことが可能になる。

URL

dojo.io.bindを使うことで、ブラウザのロケーションバーのURLを変えることもできる。URLを指定するには、stateオブジェクトのchangeUrlプロパティを使う。

changeUrlプロパティの値としてstringを指定したときは、Urlの最後に#の後に続けて、指定した値が入る。 changeUrlプロパティの値としてtrueを指定すると、dojoが自動的にユニークな値を設定する。

ブラウザの状態を示す情報をURLに指定して、URLが指定されたら状態を復元ようにすることで、ユーザはブックマークに状態を追加したり、他の人にブラウザの状態を伝えることができるようになる。

同じ値をchangeUrlに続けて含むstateオブジェクトを渡したときは、ブラウザの履歴には1つのstateオブジェクトだけが残る。

addToHistory()を呼び出すときにchangeUrlを使うときは、必ずchangeUrlを使うようにしなければならない。changeUrlを使わないaddToHistory()呼び出しが含まれていると正しく動作しない。

サンプルコード

<html>
  <head>
    <title>Dojo Demos</title>
    <script type="text/javascript">
      var djConfig = { isDebug: true, preventBackButtonFix: false };
    </script>
   
    <script type="text/javascript" src="dojo.js"></script>
    <script type="text/javascript">
dojo.require("dojo.lang.declare");
dojo.require("dojo.undo.browser");

function buttonPressed(){
  dojo.byId('message').innerHTML = 'buttonPressedが押されました。';
  dojo.undo.browser.addToHistory(new State('button 1'));
}

function buttonPressed2(){
  dojo.byId('message').innerHTML = 'buttonPressed2が押されました。';
  dojo.undo.browser.addToHistory(new State('button 2'));
}      

function init(){
  dojo.declare("State", null, {
    initializer: function(name){
      this.name=name;
    },
    back: function() {
        dojo.debug("Back was clicked in "+this.name);
    },
    forward: function() {
        dojo.debug("Forward was clicked in "+this.name);
    }
  });
      
  dojo.undo.browser.setInitialState(new State("initial"));

  var historyButton = dojo.byId('historyButton');
  var historyButton2 = dojo.byId('historyButton2');
  dojo.event.connect(historyButton, 'onclick', 'buttonPressed');
  dojo.event.connect(historyButton2, 'onclick', 'buttonPressed2');
}

dojo.addOnLoad(init);
    </script>
  </head>
 
  <body>
    <button id="historyButton">Press Me 1</button>
    <button id="historyButton2">Press Me 2</button>
    <div id="message"></div>
  </body>
</html>

« publish/subscribe | トップページ | 配列 »

コメント

コメントを書く

(ウェブ上には掲載しません)

トラックバック

この記事のトラックバックURL:
http://app.f.cocolog-nifty.com/t/trackback/232684/5798876

この記事へのトラックバック一覧です: ブラウザのバックボタン/履歴への対応:

« publish/subscribe | トップページ | 配列 »