Qiita Teams that are logged in
You are not logged in to any team

Log in to Qiita Team
Community
OrganizationAdvent CalendarQiitadon (β)
Service
Qiita JobsQiita ZineQiita Blog
45
Help us understand the problem. What is going on with this article?
@Web_akira

jQuery で作るシングルページ・アプリケーション(SPA) 70行で動くサンプル付き

More than 1 year has passed since last update.

※ だいぶ前に書いた記事ですが、未だに見られているようなので、デモページを作って末尾に追記しました。(2020/03/31)


こんにちは。jQuery 大好きです。
SPAが気になるこの頃です。

AngularJS や Vue.js を時間のある時にさわって、何とか使えることが分かりホッとしていますが、もっと簡単に使えないものかな、と思っていました。
フレームワークを使うまでもなく、小規模のウェブアプリを、SPAでサクッと作れるようになりたい。

ブレイクスルーJavaScript』を読むと、フレームワークなしでSPAを作る手法が掲載されていました。

なるほど、こういうことか、と合点がいきました。
SPAは、「ハッシュタグを使って、画面遷移を実装する」と理解しました。
AngularJS でもそうでした。
調べたところ、このハッシュタグの取得は、jQuery でも、プラグインを入れれば実装できると分かりました。
※このプラグインは、最新のjQueryで使うためには、多少手を加えるところがありますが、IE6からも対応しています。心強いですね。

以下のサンプルは、ボタン押下で画面遷移を行い、最後の画面に到達したら、ブラウザの「戻る」ボタンを押しても戻れない、というSPAです。
用途として、メールフォームを想定しています。メール送信完了後に、前の画面に戻ってほしくないので。
70行で(ひとつのHTML)で、3画面を表現できます。
2画面目は、ブラウザの「戻る」ボタンで、前に戻ることもできます。

まず、事前処理として、以下のリンクから、jQuery でハッシュタグのイベントを使えるようにするためのプラグインをダウンロードします。
圧縮版でかまいません。
http://www.koikikukan.com/archives/2013/03/22-025555.php
次に、jQuery 1.9系、2系では、以下の変更が必要です。

変更前
$.browser.msie &
変更後
$.support.msie &

これだけです。準備OK!

プラグイン導入後は、.hashchange というイベント、ハッシュタグが変更された時のイベントが使えるようになります。
ハッシュタグ自体は、location.hash で取得できますし、これに値を上書きすることができます。

hashchange.js
$(window).hashchange( function(){
    alert( location.hash );
    console.log('ハッシュが変わりました');
});

以下が、「最後の画面(完了画面)まで進んだら、戻れない」SPAになります。

spa.html
<!DOCTYPE html>
<html lang="ja">
<head>
    <meta charset="UTF-8" />
    <title>Single Page App</title>
<style type="text/css">
.page { display: none; }
</style>
</head>
<body>
    <div id="one" class="page">
        <h1>One</h1>
        <button class="btn" data-hash="two">Twoへ</button>
    </div>
    <div id="two" class="page">
         <h1>Two</h1>
        <button class="btn" data-hash="three">Threeへ</button>         
    </div>
    <div id="three" class="page">
         <h1>Three</h1>
    </div>
<script type="text/javascript" src="http://code.jquery.com/jquery-2.1.1.min.js"></script>    
<script type="text/javascript" src="jquery.ba-hashchange.min.js"></script>    
<script type="text/javascript">
$(function(){
    // 初期表示
    if( location.hash === ''){
        displayPage("#one");
    }else{
        displayPage(location.hash);
    }
    // 完了フラグ(falseになったら遷移は不可にする) 
    // 途中でURLを変更しても、falseになっていたら遷移不可
    var completeFlg = true;

    // ボタン押下のページ遷移処理
    // ハッシュのみ変更する
    $('.btn').click(function(e){
        e.preventDefault();
        var hash = "#"+$(this).attr('data-hash');
        location.hash = hash;
    });

    // ハッシュが変更されたら、そのハッシュに基づいて表示する
    $(window).hashchange(function(){
        if(completeFlg === true){
            clearPage();
            displayPage(location.hash);        
        }else{
            location.hash = "#three";    
            return false;
        }
        if(location.hash === "#three"){
            completeFlg = false;
        }
    });    

    // ページ初期化処理
    function clearPage(){
        $(".page").css("display", "none");
    }
    // ページ表示処理
    function displayPage(hash){
        $(hash).css("display", "block");
        // $(hash).fadeIn(2000, "linear"); // アニメーションをつけることも出来る
    }
});    
</script>    
</body>
</html>

最初に、ページに相当するDIVをCSSで非表示にしています。
JSでやると、一瞬表示されてから消えるというタイムラグが発生しますので、ここはCSSに任せます。
また、最初のアクセス時には、ハッシュタグがついていないことを想定しています。

ブレイクスルーJavaScript』を読んだなら、もっとこうすればいいのに、など意見がありましたら、ぜひコメントをお願いします。
SPAの構造が理解できたら、jQuery で実装したくなり、やってみた結果が、このサンプルコードになります。

※ デモサイト: https://web-atelier-midori.com/spa/spa.html

※この記事は個人ブログでも掲載しています。http://web-atelier-midori.com/blog/javascript/1681/

45
Help us understand the problem. What is going on with this article?
Why not register and get more from Qiita?
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away
Web_akira
好きな言語は PHP。jQuery との組み合わせでご飯を食べてきましたが、2019年から Vue.js も使い出しました。好きなフレームワークは、Laravel, Slim、Twitter Bootstrap4、Materialize。デザインを少しかじっています。WordPress で独自テーマを作ったり、デザイナーさんと連携してお仕事をします。人の役に立つものを作りたいと思っています。

Comments

No comments
Sign up for free and join this conversation.
Sign Up
If you already have a Qiita account Login
45
Help us understand the problem. What is going on with this article?