jQueryのAjaxやタブ切替などでブラウザの「戻る」「進む」が有効になる「hashchangeプラグイン」(実装解説つき)

jQueryのAjaxやタブ切替などでブラウザの「戻る」「進む」が有効になる「hashchangeプラグイン」(実装解説つき)

Posted at March 22,2013 2:55 AM
Tag:[hashchange, jQuery, Plugin]

jQueryのAjaxやタブ切替などでブラウザの「戻る」「進む」が有効になる「hashchangeプラグイン」を紹介します。

jQuery hashchangeプラグイン
jQuery hashchangeプラグイン

1.機能

Ajaxを使って切り替えたページについては、通常、ブラウザの「戻る」「進む」が使えません。

が、hashchangeプラグインを利用すれば、Ajaxを使って切り替えたページについてもブラウザの「戻る」「進む」が有効になります。

例えば下の図の①~⑤のページ遷移で、通常は「戻る」「進め」ボタンで②~④の遷移は行われませんが、hashchangeプラグインを使えば②~④のページ遷移も実現できます。

ページ遷移例

具体的な仕組みですが、まず基本的なJavaScriptの動作として、フラグメント(「index.html#abc」の「#abc」)を使ってページを切り替えた場合、フラグメント「#abc」が「location.hash」に設定されます。

hashchangeプラグインは、このlocation.hashの変更をイベントとしてハンドリングできるようにするものです。

つまり、ブラウザの「戻る」「進む」をクリックしたときに、location.hashでハンドリングできるようになるので、ハンドリング後はlocation.hashを使って適切な処理を行えば、ブラウザの「戻る」「進む」に連動してページの履歴を辿るように見せることができる、という仕組みです。

他のjQueryプラグインでは比較的簡単に設定できますが、hashchangeプラグインはlocation.hashを使った実装が必要な点が大きく異なります。

ちなみに、HTML5で導入されたpushStateとpopStateで同様の機能が実現できるみたいですが、IEが対応していないようです。

ソースコードを見る限り、hashchangeプラグインはIE6/7/8にも対応しているようです。

2.プラグインのダウンロード

公式サイトにある「Source」または「Minified」を右クリックして、ファイルをダウンロード。

公式サイト

ファイル名は「jquery.ba-hashchange.js」または「jquery.ba-hashchange.min.js」とします。

3.基本的な使い方

jQueryと、ダウンロードした「jquery.ba-hashchange.js」または「jquery.ba-hashchange.min.js」を読み込みます。

<script type="text/javascript" src="http://ajax.googleapis.com/ajax/libs/jquery/1.8.2/jquery.min.js"></script>
<script src="jquery.ba-hashchange.min.js"></script>

hashchangeイベントを受け取りたい要素に対して次のように記述します。「hashを使った処理」の詳細な実装方法については次項で解説します。

<script>
$(function(){
    $(window).hashchange(function(){
        var hash = location.hash;
        // hashを使った処理
    })
    $(window).hashchange();
});
</script>

なお、jQuery1.9系では「TypeError: $.browser is undefined」というエラーが出るようなので、ここでは1.8系を使用しています。

1.9系を利用する場合は、jquery.ba-hashchange.jsの下記の部分を修正してください。

変更前

$.browser.msie && !supports_onhashchange && (function(){

変更後

$.support.msie && !supports_onhashchange && (function(){

4.サンプル

次のサンプルで動作を確認してください。

サンプル
サンプル

ボックスをクリックするとボックスの背景色が変わります。

何回かクリックした後でブラウザの「戻る」をクリックしても通常は何も起こりませんが、hashchangeプラグインを利用しているので、クリックした順番と逆の順番で色が変わっていきます。

サンプルの内容は次のとおりです(一部割愛)。

<style type="text/css" title="text/css">
a {
    display: block;
    padding: 15px;
}
a.selected {
    background: #ccc; 
}
</style>
<script type="text/javascript" src="http://ajax.googleapis.com/ajax/libs/jquery/1.8.2/jquery.min.js"></script>
<script src="jquery.ba-hashchange.min.js"></script>
<script>
$(function(){
    $(window).hashchange(function(){
        var hash = location.hash;
        $('a').each(function(){
            if ($(this).attr('href') == hash) {
                $(this).addClass('selected');
            } else {
                $(this).removeClass('selected');
            }
        });
    })
    $(window).hashchange();
});
</script>
<ul>
  <li><a href="#test1">test1</a></li>
  <li><a href="#test2">test2</a></li>
  <li><a href="#test3">test3</a></li>
</ul>

キモとなるのは次の赤色部分で、hashchangeイベントが発生したときに、背景色を切り替える処理を行っています。

$(function(){
    $(window).hashchange(function(){
        var hash = location.hash;
        $('a').each(function(){
            if ($(this).attr('href') == hash) {
                $(this).addClass('selected');
            } else {
                $(this).removeClass('selected');
            }
        });
    })
    $(window).hashchange();
});

もしhashchangeイベントが不要な処理であれば、例えば次のような実装になるかと思います。

$(function(){
    $('a').click(function(){
        $('a').each(function(){
            $(this).removeClass('selected');
        });
        $(this).addClass('selected');
    });
});

話を戻して、ボックスをクリックするとhashchangeイベントが発生し、次の行を実行します。一番右のボックスをクリックした場合、変数hashには「#test3」が設定されます。

        var hash = location.hash;

あとは、すべてのa要素をチェックして、href属性の値が変数hashと等しければclass属性値「selected」を追加し、そうでなければ削除します。

        $('a').each(function(){
            if ($(this).attr('href') == hash) {
                $(this).addClass('selected');
            } else {
                $(this).removeClass('selected');
            }
        });

一番最後にある

    $(window).hashchange();

は、ブラウザをリロードしたときにhashchangeイベントを発生させるためのものです。

5.実装のポイント

サンプルにおける実装のポイントは、ブラウザの「戻る」「進む」の処理と、普通にクリックしたときの処理が1つになっているということです。

なぜなら、a要素を普通にクリックしてもlocation.hashは変更され、hashchangeイベントが発火するためです。

よって、次の実装は同じ処理が2回行われることになってしまいます。

<script>
$(function(){
 
    // a要素がクリックされたときの処理
    $('a').click(function(){
        $('a').each(function(){
            $(this).removeClass('selected');
        });
        $(this).addClass('selected');
    });
 
    // hashchangeイベント処理
    $(window).hashchange(function(){
        var hash = location.hash;
        $('a').each(function(){
            if ($(this).attr('href') == hash) {
                $(this).addClass('selected');
            } else {
                $(this).removeClass('selected');
            }
        });
    })
    $(window).hashchange();
});
</script>

以上です。

jQuery UIを使ったタブ切り替えでhashchangeプラグインを利用する方法については、別エントリーします。

関連記事
トラックバックURL


コメントする
greeting

*必須

*必須(非表示)


ご質問のコメントの回答については、内容あるいは多忙の場合、1週間以上かかる場合があります。また、すべてのご質問にはお答えできない可能性があります。予めご了承ください。

太字イタリックアンダーラインハイパーリンク引用
[サインインしない場合はここにCAPTCHAを表示します]

コメント投稿後にScript Errorや500エラーが表示された場合は、すぐに再送信せず、ブラウザの「戻る」ボタンで一旦エントリーのページに戻り(プレビュー画面で投稿した場合は、投稿内容をマウスコピーしてからエントリーのページに戻り)、ブラウザをリロードして投稿コメントが反映されていることを確認してください。

コメント欄に(X)HTMLタグやMTタグを記述される場合、「<」は「&lt;」、「>」は「&gt;」と入力してください。例えば「<$MTBlogURL$>」は「&lt;$MTBlogURL$&gt;」となります(全て半角文字)