非同期通信でページを切り替えって?
そもそも通常の画面遷移をする場合、新しいページを1から読み込んで表示すると思います
この場合まず画面を遷移し、(ほとんどの場合は気になりませんが)新しい白いページが表示されてから目的のページが読み込まれていきます
これは通常のページ遷移が「同期通信」という通信方法でサーバとやりとしているためです
対して「非同期通信」とは、例えばGoogle Mapのように画面遷移を行わずにページ遷移をするような通信方法を言います
(DEMOもをご参照いただけると分かりやすいかと)
ここの詳しい部分はこちらのページで分かりやすく詳しく説明されててオススメです
(僕が「なんとなく分かるけど説明できるほど理解できてない」状態なので・・・)
初心者目線でAjaxの説明
この「非同期通信」をJavaScriptを利用して行うのが「Ajax」という仕組みになります
そしてこの「Ajax」とHTML5で追加された「pushState」というURLを操作できるAPIを利用して、ページ遷移を非同期でシームレスに行おうというjQueryプラグインに「jquery-pjax」というものがあります
「jquery-pjax」を導入することで、非同期通信で新しいページを読み込み、あたかもページ遷移をしていないようにシームレスでスムーズなページ遷移を行うことが出来ます
そしてそしてこの「jquery-pjax」をさらに使いやすくかつjQuery無しでも動作するように作られたのが「barba.js」です
wordpressはjQueryのバージョン等の制限が多いのでbarba.jsは導入しやすいと思ったのですが、ちょっとハマったのでそこのご紹介です
barba.jsとは
barba.jsとは上記でも説明したとおりpjaxを使いやすくしたようなJavaScriptのライブラリになります
シームレスでスムーズなページ遷移を実現することが出来ます
barba.jsの導入方法
必要なファイル
導入に必要なものは「barba.min.js」本体と設定用のJSファイルです
本体は本家サイトかGitHubから入手できます
設定用ファイルは個別作成して下さい、ファイル名は参考ページに習って「barba-custom.js」とします
これを「テーマディレクトリ/js/」ディレクトリ内に入れておきます
追加方法
テーマディレクトリにJSファイルを追加して、普通にHTMLタグで読み込む方法とfunction.phpで読み込む方法があります
HTMLタグで読み込む場合
<script src="<?php echo get_template_directory_uri(); ?>/js/barba.min.js" type="text/javascript"></script> <script src="<?php echo get_template_directory_uri(); ?>/js/barba-custom.js" type="text/javascript"></script>
function.phpで読み込む場合
※wp_enqueue_script()の第5引数をtrueにすると</body>タグの直前で読み込まれ、falseにすると<head>タグ内で読み込みます。
※barba.jsをCDNから読み込む場合は参考ページをご参照下さい
function my_enqueue_scripts() { // barba.js本体の読み込み wp_enqueue_script( 'barba', get_template_directory_uri() . '/js/barba.min.js', array(), false, true ); // barbar-custom.jsの読み込み wp_enqueue_script( 'barba-custom', get_template_directory_uri() . '/js/barba-custom.js', array(), false, true ); } add_action( 'wp_enqueue_scripts', 'my_enqueue_scripts' );
HTMLタグの設定
非同期で読み込みたい部分を「<div id=”barba-wrapper”><div class=”barba-container”></div></div>」で囲みます
ヘッダーとフッターは基本的には固定になりますので中身のコンテンツを囲ってあげる感じになると思います
部分的に囲って使用することも可能です
<div id="barba-wrapper"> <div class="barba-container"> <!-- 動的コンテンツ --> </div> </div>
barba.jsの設定ファイルの設定
ここでちょっとハマりました
設定がかなり細かく出来るのですが、意図した動作をさせるのになかなか手こずりまして
色々調べていた所参考ページ様にたどり着いたのでそちらから引用させていただきます
@SimmonさんのQiita
// 現在と同じページのリンクをクリックした場合、リロードをしない設定(オプション) // リロードしたい場合は削除してOKです。 var links = document.querySelectorAll('a[href]'); var cbk = function(e) { if(e.currentTarget.href === window.location.href) { e.preventDefault(); e.stopPropagation(); } }; for(var i = 0; i < links.length; i++) { links[i].addEventListener('click', cbk); } /* * 遷移時に変更したい処理 * デフォルトではhead内のmetaタグは変わりません。(titleタグは変わります) * また、barba-container内のjsは実行されないので個別に変更・実行したい処理をココに書きます。 */ Barba.Dispatcher.on('newPageReady', function(currentStatus, oldStatus, barbaContainer, newPageRawHTML) { if ( Barba.HistoryManager.history.length === 1 ) { // ファーストビュー return; // この時に更新は必要ありません } // jquery-pjaxから借りた var $newPageHead = $( '<head />' ).html( $.parseHTML( newPageRawHTML.match( /<head[^>]*>([\s\S.]*)<\/head>/i )[ 0 ], document, true ) ); // 変更したいタグ(ご自身の環境に合わせて適宜変更してください) var headTags = [ "link[rel='canonical']", "link[rel='shortlink']", "link[rel='alternate']", "meta[name='description']", "meta[property^='og']", "meta[name^='twitter']", "meta[name='robots']" ].join( ',' ); $('head').find(headTags).remove(); // タグを削除する $newPageHead.find(headTags).appendTo('head'); // タグを追加する // Analyticsにヒットを送信(Google Analyticsを導入している場合) if (typeof ga === 'function') { ga('send', 'pageview', location.pathname); } // 外部ファイルを任意の場所に追加して実行する(オプション) // 外部ファイルにdocument.write()が書かれていると、それは無視されますので正常に表示されません。 var script = document.createElement('script'); script.src = 'http://example.com/hoge.js'; document.body.appendChild(script); // インラインに書いたjsを実行する(オプション) var temp = document.createElement('div'); temp.innerHTML = newPageRawHTML; var hoge = temp.querySelector('.hoge script'); if(hoge != null){ eval(hoge.innerHTML); } }); // End Dispatcher // アニメーションの設定(フェードアウト→フェードイン)(オプション) // 必要ない場合は削除してOKです。 var fadeTransition = Barba.BaseTransition.extend({ start: function() { //startはトランジションが起動した直後の一番最初に呼び出される。 //promise.allを使うと、配列で渡された処理が全て終わった後に.thenを実行。 //この場合は.newContainerLOadingと.fadeOutが終わってから.thenが実行される。 Promise .all([this.newContainerLoading, this.fadeOut()]) .then(this.fadeIn.bind(this)); }, // End start function fadeOut: function() { //古いページコンテンツに対して行う処理。 //ここでは、animateを使って、fadeoutさせている。 return $(this.oldContainer).animate({ opacity: 0 },{duration:'fast'}).promise(); }, fadeIn: function() { // topに移動(地味に重要) document.body.scrollTop = 0; //startに記述したallによって、fadeOutが終わったらこのfadeIn関数が呼び出されている。 var _this = this; //ここでのnewContainerは、ajaxで読み込まれてきた新しい方の.barba-containerにあたる。 var $el = $(this.newContainer); //opacity:0;になっていた古いbarba-containerをdisplay:none;に。 //こちらおそらくfadeIn発動時古いbarba-containerの初期設定として。 $(this.oldContainer).hide(); //こちらも新しいbarba-containerの初期設定。 //visiblityがあるのは、デフォルトではこれがhiddenになってるっぽいから。 $el.css({ visibility : 'visible', opacity : 0 }); $el.animate({opacity: 1}, 200, function() { //.done()をつけることで古いbarba-containerのDOMは削除され、transitionが終了する。 _this.done(); }); } }); // End BaseTransition // returnに作ったトランジションを設定 Barba.Pjax.getTransition = function() { return fadeTransition; }; // barba実行 $().ready(function(){ Barba.Pjax.start(); Barba.Prefetch.init(); // prefetchを有効化 });
その他設定は本家サイトもご参照下さい
APIやTransition、Eventも用意されてていたれりつくせりです
非同期通信の無効化の仕方
「このリンクをクリックしたときの遷移は非同期にしたくない」といった場合は<a>タグに「no-barba」というクラスを設定してあげます
<a href="/test/" class="no-barba">このリンクは非同期したくない</a>
例えばカテゴリごとにヘッダ画像が違う場合にカテゴリリンクに設定したり、英語版と日本語版ページでデザインが異なる場合などに設定すると良いです
まとめ
「jquery-pjax」自体はかなり前からありましたが「barba.js」はわりと最近のものだと思います
使用してみた感想ですが、設定に苦戦しましたが使用感はかなり良かったです
そしてページの読み込みはかなり速くなります、webページと言うよりはアプリとかに近い体験を提供できるようになるのではと思います
(サーバスペックや回線状況にもよりますが)
下記参考サイト様
【爆速】WordPressで始めるpjax入門
初心者目線でAjaxの説明
willstyle
脱jQuery!?、Barba.js使ってみた。
シームレスなページ遷移を!PJAXの実装に便利な軽量プラグイン Barba.js の使い方
jQueryプラグイン「pjax」でスムーズにページ遷移するサイトの作り方
コメント