こんばんは!今日はjQueryプラグインのPJAXを利用してみましたので、そのソースやサンプルを公開したいと思いますっ!

PJAXとは?

まずPJAXって何なのでしょう・・・?

history.pushStateというものとAJAXを組み合わせたものがPJAXであります!!

・・・

意味わからんね・・・

実はHTML5になってからHISTORY APIというものが追加されました。(正確には以前からあったけれども、今回のPJAXに繋がる機能が追加されました)
難しいことは考えず、Javascriptとかで利用できる項目が増えたって思ってもらえればわかりやすいかなと。

ざっくりとHISTORY APIが何をするかと言うと、画面を遷移せずにURLを変更したりすることができます!

そして、ご存知AJAXは非同期通信で狙ったデータを入れたり、データを変更したりすることができます。

この二つの機能を兼ね備えたのがPJAXという訳です。

で、実際何がどうなるの?

ホームページを見ていると、たまにヘッダーとか全く変わらずにコンテンツだけ変わって、さらにURLも変わっている。みたいなページを見たことないでしょうか?

初めて見た時はなんじゃこれ!?と思ったものです。
で、色々と調べていると、HISTORY APIというものに辿り着き、今回のPJAXに辿り着きました。

とりあえず今回作ってみたデモを見てみてください。

DEMO

とりあえずこれを作ってみよう

説明するよりもソースを見てもらった方がわかりやすいかと思うので、サクッと行きましょうっ!

今夜のメニュー
・HTML二種類(遷移前と遷移後)
・SCSS(スタイル用)
・jQuery

では早速HTMLを作りましょう!!
という前にjQueryとPJAXプラグインをリンクさせましょう!今回はCSSとかも必要なのでheadタグはこんな感じ

<head>
    <meta charset="UTF-8">
    <title>Pjax test</title>
    <link href='https://fonts.googleapis.com/css?family=Roboto:700,300' rel='stylesheet' type='text/css'>
    <link rel="stylesheet" type="text/css" href="css/style.css">
    <link rel="stylesheet" type="text/css" href="../normalize.css">
    <script src="//code.jquery.com/jquery-1.11.3.min.js"></script>
    <script src="pjax.min.js"></script>
    <script src="pjax_test.js"></script>
</head>

ちなみにPJAXはこちらでダウンロードできますっ!

では、遷移前のHTMLファイル(index.html)を作りましょう!こんな感じ

<body>
<header>
    <h1 class="logo">LOGO</h1>
    <nav>
        <ul class="nav-items">
            <li class="nav-items-contents">THIS</li>
            <li class="nav-items-contents">IS</li>
            <li class="nav-items-contents">PJAX</li>
            <li class="nav-items-contents">SAMPLE</li>
            <li class="nav-items-contents">PAGE</li>
        </ul>
    </nav>
</header>

<section id="pjaxContent" class="pjax-test">
    <h2 class="pjax-test-title">This is page <span>ONE</span></h2>
    <div><a class="btn" href="next.html">Click To Change</a></div>
    <div class="clear">
        <div class="pjax-test-contents"></div>
        <div class="pjax-test-contents"></div>
        <div class="pjax-test-contents"></div>
        <div class="pjax-test-contents"></div>
        <div class="pjax-test-contents"></div>
        <div class="pjax-test-contents"></div>
        <div class="pjax-test-contents"></div>
        <div class="pjax-test-contents"></div>
    </div>
    <div><a class="btn" href="next.html">Click To Change</a></div>
</section>

<section class="links">
    <h2 class="links-title">LINKS</h2>
    <ul class="links-all">
        <li class="links-all-item"><a href="http://falsandtru.github.io/jquery-pjax/api/" target="_blank">PJAX API</a></li>
    </ul>
</section>


<footer>
<p>this is footer</p>
</footer>
</body>

ありがちな感じにしてみましたっ!
ロゴがあって、ナビがあって、コンテンツが2カラム。
まぁ説明不要だと思うので、続いて遷移後のHTMLを作成!!名前はnext.htmlにしてみましたっ!
headタグは同じなので省略していきますねー

<body>
<section id="pjaxContent" class="pjax-test-two">
    <h2 class="pjax-test-two-title">This is page <span>TWO</span></h2>
    <div><a class="btn" href="./">Click To Change</a></div>
    <div class="clear">
        <div class="pjax-test-two-contents"></div>
        <div class="pjax-test-two-contents"></div>
        <div class="pjax-test-two-contents"></div>
        <div class="pjax-test-two-contents"></div>
        <div class="pjax-test-two-contents"></div>
    </div>
    <div><a class="btn" href="./">Click To Change</a></div>
</section>
</body>

こちらは簡単に違いがわかるように1カラムレイアウトに変更しましたっ!

さて、ここで注目してほしいのは、index.htmlと違ってヘッダーやフッター部分はなく、コンテンツのみの表記にしています。
PJAXが本当にコンテンツのみを変えている!というのを分かりやすくするためですっ!

本番でこれをすると、ページをリロードしたり、ランディングがこのページだったらヘッダーとかフッターが無くなってしまうので、絶対にやらないでくださいねー!

では、続いてSCSSを作成!コードは必要ないような気もしますが、念のため載せておきます・・・

//RESET
body,h2{
    font-family: 'Roboto', sans-serif;
    margin: 0;
    padding: 0;
}
body{
    -webkit-font-smoothing: antialiased;
    overflow-x: hidden;
}
a{
    color: inherit;
    text-decoration: none;
}

//STYLE
$link : #88ACD2;

.clear{
    overflow: hidden;
}

header{
    width: 100%;
    max-width: 1000px;
    margin: 0 auto;
    overflow: hidden;

    .logo{
        width: 10%;
        color: #ccc;
        float: left;
        font-weight: 300;
    }

    .nav-items{
        width: 80%;
        border-radius: 4px;
        color: #5a5a5a;
        display: flex;
        float: right;
        list-style: none;
        margin-left: 5%;
        padding: 0;

        &-contents{
            width: 25%;
            background-color: #eee;
            font-weight: 300;
            padding: 20px 0;
            text-align: center;

            &:not(:first-child){
                border-left: 1px solid #dedede;
            }
        }
    }
}

.links{
    width: 100%;
    max-width: 1000px;
    background-color: #eee;
    box-sizing: border-box;
    margin: 80px auto 0;
    padding: 40px;

    &-title{
        color: #5a5a5a;
        font-weight: 300;
    }

    &-all{
        padding-left: 1em;

        &-item{
            color: $link;
            font-weight: 300;
            text-decoration: underline;
        }
    }
}

.pjax-test{
    width: 100%;
    max-width: 1000px;
    margin: 40px auto 0;

    &-title{
        color: #5a5a5a;
        font-size: 2em;
        font-weight: 300;

        span{
            color: #7BABD2;
            font-weight: 700;
        }
    }

    &-contents{
        width: 49%;
        height: 300px;
        background-color: #ccc;
        float: left;
        margin-top: 20px;

        &:not(:nth-child(2n + 1)){
            margin-left: 2%;
        }
    }
}

.pjax-test-two{
    width: 100%;
    max-width: 1000px;
    margin: 40px auto 0;

    &-title{
        color: #5a5a5a;
        font-size: 2em;
        font-weight: 300;

        span{
            color: #7FD2B1;
            font-weight: 700;
        }
    }

    &-contents{
        width: 100%;
        height: 300px;
        background-color: #ccc;
        margin-top: 20px;
    }
}


.btn{
    width: 10em;
    border: 1px solid $link;
    border-radius: 4px;
    color: $link;
    display: block;
    font-weight: 400;
    margin-top: 40px;
    padding: 10px;
    text-align: center;
    transition: .3s;

    &:hover{
        background-color: $link;
        color: #fff;
    }
}


footer{
    width: 100%;
    background-color: #ccc;
    margin: 80px 0 0;

    p{
        width: 100%;
        color: #5a5a5a;
        margin: 0;
        padding: 40px 0;
        text-align: center;
    }
}


//アニメーション用
$time : .5s;
$ease : cubic-bezier(0.25, 0.46, 0.45, 0.94);

#pjaxContent{
    position: relative;

    &.fadeIn{
        animation: fadeIn $time $ease;
    }
    &.fadeOut{
        animation: fadeOut $time $ease;
    }
    &.fadeOutDelay{
        animation: fadeOut $time .4s $ease;
    }
}

@keyframes fadeIn{
    0%{left: 100%;}
    100%{left: 0;}
}
@keyframes fadeOut{
    0%{left: 0;}
    100%{left: -100%;}
}

特に変わったことはないですね!注意点としては、animationとかkeyframes、transitionはまだプレフィックスが必要なので注意ですね!

ちなみにボクはgulpで自動化しております。

このアニメーションはページ遷移の時のアニメーションを設定しています!ここを色々触ることで遷移時に様々な動きを持たせることができるんですねー!
(名前がfadeinとかなのにデモはフェードしてないのはあしからず・・・元々フェードで作ってたのだ・・・)

さて、最後に今回のキモ、jQueryファイルにいきましょう!!
まずはコード!!

$(function(){
     $.pjax({
         area : '#pjaxContent', // 遷移するエリアを指定
         link : '.btn', // イベント発火のターゲットを指定できる
         ajax: { timeout: 3000 }, // 読み込みにこれ以上かかる場合は通常遷移
         wait : function(){// エフェクト分の待ち時間を作る(関数可)
            var wScr = $(window).scrollTop();
            if(wScr){
                return 800;
            }else{
                return 400;
            }
         }
     });

     $(document).on('pjax:fetch',function(){ // 消える時の処理
         var wScr = $(window).scrollTop();

         if(wScr){
            $('body,html').animate({scrollTop : 0},'200');
            $('#pjaxContent').removeClass('fadeIn').addClass('fadeOutDelay');
         }else{
            $('#pjaxContent').removeClass('fadeIn').addClass('fadeOut');
         }

         //直接書いてもよい
         // $('#pjaxContent').animate({
         //     'left' : '-10px',
         //     'opacity' : 0
         // }, 500);
     });

     $(document).on('pjax:render',function(){ // 現れる時の処理
         $('#pjaxContent').removeClass('fadeOut').addClass('fadeIn');

         //直接書いてもよい
         // $('#pjaxContent').animate({
         //     'left' : 0,
         //     'opacity' : 1
         // }, 500);
     });
});

今回のデモの場合はこんな感じですっ!

ボタン押してページ遷移してる風、さらにURLも変わっているでしょう!?
next.htmlにはヘッダー、フッターを書いていないのに存在しているでしょう!?

これがPJAXだ!!

DEMO

これを作るにあたってボクも色々調べながらやったのですが、見るサイトによって書き方が違っていたので少しとまどいました・・・PJAXプラグインっていくつかあるのかな・・・?

ボクが使ったプラグインは上記の書き方で動きました!
今回のデモでは上と下の二箇所にボタンを設置しましたが、下のボタンを押した時は一旦一番上までスクロールしてから遷移する。というのを作りたかったのです。

ということは上のボタンを押したらすぐにページ遷移、下のボタンを押した場合はスクロール分の時間を待ってからページ遷移処理が必要なので、それぞれの時間の調整が必要だったのですが、少し戸惑いました・・・

ポイントは$.pjaxの中のwaitの部分!!
一つしか無理だと思ってたのですが、関数でもいけるというのを発見しました。

さすがですなぁ・・・

簡単に全体の内容を説明すると、

・$.pjaxの部分で全体の設定が可能
・pjax:fetchの部分で遷移前のアニメーションなどの処理を設定
・pjax:renderの部分で遷移後のアニメーションなどの処理を設定
・pjax:fetchとpjax:renderの部分は直接処理を書くことも可能

今回はこれしか使わなかったですが、他にも色んなAPIが用意されていました!
一応デモの中にもリンクがあるので、気になる方は見てみてくださいっ!
もっと細かい設定ができるみたいなので、時間あれば色々試してみたいなー

エライ長くなってしまいましたが・・・

今回はずっと気になっていたPJAXプラグインのご紹介でしたっ!
ありがとうございました!