memorandum
thinking about creation

手軽にSPA?jquery-pjaxを使ってみる

Entry Date _ 2016.09.21
/
ModifiedDate _ 2016.10.04
pjax.jpg

PJAX(jquery-pjax)を試してみたのでメモっておきます。

すでに手軽にSPA的なことが実現できるという以外に実用性はないようにも思うのだが、手軽さこそ力だということで使ってみることにしました。

PJAXを簡単に言えば、「pushState」と「ajax」を組み合わせたもの、つまりページの非同期遷移をしつつURLを操作をする技術だ。

ヘッダーとフッターはどのページも共通で、コンテンツのみが違う構成のサイトがあるとする。通常ならばリンクでページをまるごと読み込みながら遷移していくわけだが、PJAXを使えば指定したコンテンツの部分のみを非同期で更新していくことが可能になる。

PJAXで作られたコンテンツは、厳密に言えばSPA(シングルページ・アプリケーション)にならない。しかし、そこが良いところでもある。どういうことかと言うと、非同期遷移するにも関わらずアドレスは更新されるからだ。

SPAは、その名の通りシングルページ、ひとつしかファイルが存在しないので、画面上でコンテンツが更新されたとしても、アドレスは変わらない。しかし、PJAXの場合、それぞれのページが用意してあり、アドレスも更新されるのだ。これならば、URLをブックマークしておけばダイレクトに情報にたどり着けるし、SEOにうるさいクライアントの要望にも応えることができる。

PJAXを実現する javaScriptライブラリには、「falsandtru」の ajax-api.js と、「defunkt」の jquery-pjax が存在するが、より手軽な方をということで jQueryプラグインである「defunkt」版を使ってみた。

さて、サンプルを見ていただこう。サンプルのサイトは3ページで更新されている。

まず page-1.html から見ていただけるとありがたい。ページ全体の更新はされないで、点線で囲われた部分のみが更新され、さらにURLも変わっていることがおわかりいただけるだろう。PJAXのもう一つの利点は、読み込まれるのが指定したコンテンツの部分だけなので、共通で読み込まれる画像や JavaScript ライブラリなどの再読込がなく動作が快適になることだ。

わかりやすいように、page-1.html から遷移すればPJAX、それ以外のページから遷移すると通常遷移するようにしてある。例えば page-2.html に直接アクセスするとPJAXでは表示されない「(ここはPJAXでは読み込まれません)」という文言が表示されているはずだ。

サンプルは以下のようになっている。

まずは HEAD でライブラリの読み込み


BODY の中では、PJAXで更新する部分(#pjaxContent)と、PJAXで更新させるリンク(.pjaxLink)を指定してあります。更新されるのは #pjaxContent だけです。各ページでは、.pjaxLink で指定したリンクのURLと文言を変えてください。

PJAX = pushState + ajax : header

GitHub/defunkt/jquery-pjax

#pjaxContent

PAGE-1

PAGE-2に移動する

footer

javaScriptは、通常ページを遷移させるリンクをクリックすると、フェイドイン/フェイドアウトでPJAX更新されるようになっています。

$(function(){

	var pjaxLink = '.pjaxLink'; // PJAXで更新させるセレクタ
	var pjaxContent = '#pjaxContent'; //PJAXで更新する部分のセレクタ

	/*
	 * pjaxLink がクリックされたら、
	 * pjaxContent をフェイドアウト。
	 * コールバックでPJAXを実行
	 */
	$(document).on('click', pjaxLink, function(event){
		var url = $(this).attr('href');

		$(pjaxContent).animate({
			left : -100,
			opacity : 0
		}, 'fast', function(){
			// PJAXを実行
			$.pjax({
				url: url,
				container : pjaxContent, // PJAXで更新する部分
				fragment : pjaxContent, // 読み込まれるページの更新する部分
				timeout : 1000
			});
		});

		return false;
	});

	/*
	 * PJAXが終了したらフェイドインで表示
	 */
	$(document).on('pjax:end', function() {
		$(pjaxContent).animate({
			left : 0,
			opacity : 1
		}, 'fast');
	});

});

Category

memorandum index