こんにちは、アートディレクターの奥田です。
以前、Pjaxを簡単に導入できるBarba.jsをご紹介いたしました。
前の記事:Pjax(非同期画面遷移)でシームレスな画面遷移ができるBarba.js
シームレスでかっこいいWEBサイトの制作にはBarba.jsが非常に便利なのですが、リンククリック時の動作やメタタグの取得などちょっとしたことで躓くことがあります。
今回は僕がこの1年ほどで使用してきたスニペットをご紹介したいと思います。
サイト制作のお役に立てていただければ幸いです。
Table of contents
- Google Analyticsを有効にする
- headタグ内の必要なメタタグを取得する
- 該当する拡張子がついたリンクにtarget=”_blank”をつける
- 外部リンクにtarget=”_blank”をつける
- アンカーリンクであり同一ページでなければPjaxを有効にする
- 該当クラスに属していればBarbaを無効にする
- さいごに
Google Analyticsを有効にする
Barba.jsは非同期でページ遷移をするので実際にはページ遷移しておらず、Google Analyticsにページのトラッキング情報を送信する必要があります。
こちらは公式GitHubのissueにも投稿がありましたが以下のようにして対応可能です。
また、analytics.jsとgtag.jsの場合でコードが異なるため、使い分けるとよいでしょう。
Barba.Dispatcher.on('initStateChange', function() { if (typeof ga === 'function' && Barba.HistoryManager.history.length >= 1) { ga('send', 'pageview', location.pathname); } if (typeof gtag === 'function' && Barba.HistoryManager.history.length >= 1) { gtag('config', 'トラッキングID', {'page_path': location.pathname}); } });
headタグ内の必要なメタタグを取得する
Barba.jsは上記同様head内のtitleタグ以外のmetaタグを変更できません。
こちらはjQueryで記述されたものがQiitaにありましたので僕がVanillaに書き換えてコメントしています。
Barba.Dispatcher.on('newPageReady', function(currentStatus, oldStatus, container, newPageRawHTML) { var head = document.head; var newPageRawHead = newPageRawHTML.match(/<head[^>]*>([\s\S.]*)<\/head>/i)[0]; var newPageHead = document.createElement('head'); newPageHead.innerHTML = newPageRawHead; var removeHeadTags = [ "meta[name='keywords']", "meta[name='description']", "meta[property^='og']", "meta[name^='twitter']", "meta[itemprop]", "link[itemprop]","link[rel='prev']", "link[rel='next']", "link[rel='canonical']" ].join(','); var headTags = head.querySelectorAll(removeHeadTags) for(var i = 0; i < headTags.length; i++ ){ head.removeChild(headTags[i]); } var newHeadTags = newPageHead.querySelectorAll(removeHeadTags) for(var i = 0; i < newHeadTags.length; i++ ){ head.appendChild(newHeadTags[i]); } });
その他必要なタグがあればremoveHeadTagsに追記すれば取得・置換が可能です。
該当する拡張子がついたリンクにtarget=”_blank”をつける
こちらは公式のFAQにも記載されていますが、preventCheckをカスタマイズすることでクリックされたリンクでPjaxを有効にするかを拡張することができます。
FAQ
Barba.Pjax.originalPreventCheck = Barba.Pjax.preventCheck; Barba.Pjax.preventCheck = function(evt, element) { if(element){ // ここで拡張が可能 if (!Barba.Pjax.originalPreventCheck(evt, element)) { return false; } } return true; });
公式では.pdfが含まれるリンクはBarbaを無効にする際のサンプルが掲載されています。
// No need to check for element.href - // originalPreventCheck does this for us! (and more!) if (/.pdf/.test(element.href)) { return false; }
どうせなら別タブで開けたほうが便利なので以下のようにカスタマイズしました。
// 拡張子が該当する場合はtarget="_blank"に if (/\.(xlsx?|docx?|pptx?|pdf|jpe?g|png|gif|svg)/.test(element.href.toLowerCase())) { element.setAttribute('target','_blank'); return false; }
外部リンクにtarget=”_blank”をつける
外部リンクに動的にtarget=”_blank”を付ける方法は以下のようにすれば可能です。
// 外部リンクはtarget="_blank"に var site_url = location.protocol + '//' + location.host; if (!element.href.startsWith(site_url)) { element.setAttribute('target','_blank'); return false; }
また、IE11ではstartsWithをサポートしていないので下記を記述します。
if (!String.prototype.startsWith) { String.prototype.startsWith = function(searchString, position) { position = position || 0; return this.indexOf(searchString, position) === position; }; }
アンカーリンクであり同一ページでなければPjaxを有効にする
標準のpreventCheckではURLに「#」が含まれるアンカーリンクはすべてPjaxが無効になってしまいます。
このままでは同ドメイン内で別ページのアンカーに飛ばしたい場合にPjaxが有効にならないので以下のようにして別ページのアンカーリンクの際はPjaxを有効にします。
// アンカーリンクであり同一ページでなければPjaxを有効に var url = location.protocol + '//' + location.host + location.pathname; var extract_hash = element.href.replace(/#.*$/,""); if (element.href.startsWith(location.protocol + '//' + location.host)) { if (element.href.indexOf('#') > -1 && extract_hash != url ){ return true; } }
また、アンカーリンクの際やページ遷移の際は以下のようにしてスクロールを制御してあげる必要があります。
function scroll(){ // ヘッダー追従かどうか var headerFixed = false; // URLに「#」が存在するか if(location.hash){ var anchor = document.querySelector( location.hash ); if(anchor){ var rect = anchor.getBoundingClientRect(); var scrollTop = window.pageYOffset || document.documentElement.scrollTop; if(headerFixed){ var header = document.getElementById('header'); if(header){ top = top - header.clientHeight; } } var top = rect.top + scrollTop; window.scrollTo(0,top); }else{ // アンカー先が存在しなければページトップに window.scrollTo(0,0); } }else{ // URLに「#」が存在しなければページトップに window.scrollTo(0,0); } } Barba.Dispatcher.on('transitionCompleted',scroll);
また、これは余談ですが上記例ではイベントのタイミングを”transitionCompleted”にしていますが以下のようにカスタムイベントを設定し、呼び出すことで好みのタイミングでイベントを実行できます。
// カスタムイベントを設定 Barba.Dispatcher.trigger('customEvent'); Barba.Dispatcher.on('customEvent',scroll);
該当クラスに属していればBarbaを無効にする
標準では「.no-barba」がついているリンクはPjaxが無効になります。
ですが、Wordpressのadmin-barなど「.no-barba」を付与しにくいコンテンツで Pjaxを無効にしたい場合があります。
そんなときは以下のようにすれば拡張可能です。
※Wordpressのadmin-barのリンクは「.ab-item」に属しています。
参考 https://github.com/luruke/barba.js/issues/255
// 該当クラスに属していればBarbaを無効に var ignoreClasses = ['ab-item','custom-no-barba']; for (var i = 0; i < ignoreClasses.length; i++) { if (element.classList.contains(ignoreClasses[i])) { return false; } }
さいごに
いかがだったでしょうか?
スムーズな画面遷移だけでなく、ページの高速化にも一役買っているBarba.jsのさらに便利なスニペットをご紹介しました。
皆様もぜひお試しください。