非SPAのサイトでネイティブ風な動きを実装したいと思い、Barba.jsを使ったので、その時に対応したことなどメモ。
完成したもの
gifなので、速度は結構早いですが、、、
行った手順
Barba.jsのインストール
$ npm i @barba/core
参考 : https://barba.js.org/docs/getstarted/install/
polyfill対応
IEにもBarba.jsを対応させる場合、polyfillが必要となるので、
<script
crossorigin="anonymous"
src="https://polyfill.io/v3/polyfill.min.js?features=default%2CArray.prototype.find%2CIntersectionObserver"
></script>
を追記する。
参考 : https://barba.js.org/docs/getstarted/browser-support/
基本的な遷移まで
import barba from '@barba/core'
barba.init()
<div data-barba='wrapper'>
<!-- headerなど -->
<div data-barba='container' data-barba-namespace='pageName'>
<!-- ここに変更するコンテンツを配置する -->
</div>
<!-- footerなど -->
</div>
参考 : https://barba.js.org/docs/getstarted/markup/
ページ遷移時に簡単なアニメーションを実装する
https://liginc.co.jp/476913 のコード参考
$ npm i @barba/css
import barba from '@barba/core'
import barbaCss from '@barba/css' // 追記
barba.use(barbaCss) // 追記
barba.init()
.barba-leave-active,
.barba-enter-active {
transition: opacity 0.4s ease;
}
.barba-leave {
opacity: 1;
}
.barba-enter {
opacity: 0;
}
.barba-leave-to {
opacity: 0;
}
.barba-enter-to {
opacity: 1;
}
公式 : https://barba.js.org/docs/plugins/css/
prefetch導入
$ npm i @barba/prefetch
import barba from '@barba/core'
import barbaCss from '@barba/css'
import barbaPrefetch from '@barba/prefetch' // 追記
barba.use(barbaCss)
barba.use(barbaPrefetch) // 追記
barba.init()
参考 : https://barba.js.org/docs/plugins/prefetch/
polyfill追記
自分の環境だと公式のpolyfillだけではエラーになったため、以下のコードで対応。(既存のものからNodeList.prototype.forEach
を追加しただけです。)
<script crossorigin='anonymous' src='https://polyfill.io/v3/polyfill.min.js?features=default%2CArray.prototype.find%2CIntersectionObserver%2CNodeList.prototype.forEach'></script>
polyfillについては https://polyfill.io/v3/url-builder/ を参考。
同じurlの場合、ページ遷移をさせない
同じリンク上だとページの読み込みが行われてしまうため。
参考 : https://gist.github.com/mhige/a5fe953de730afdd353e2432ace909b0#file-barba-custom-js-L3-L12
import barba from '@barba/core'
import barbaCss from '@barba/css'
import barbaPrefetch from '@barba/prefetch'
barba.use(barbaCss)
barba.use(barbaPrefetch)
barba.init()
// ここから追記
const eventDelete = e => {
if (e.currentTarget.href === window.location.href) {
e.preventDefault()
e.stopPropagation()
return
}
}
const links = [...document.querySelectorAll('a[href]')]
links.forEach(link => {
link.addEventListener('click', e => {
eventDelete(e)
}, false)
})
title
タグ以外のmetaタグの情報の書き換えを行う
公式のままだとtitle
タグは変更させますが、description
タグなどについては更新されないため。
参考 : https://gist.github.com/mhige/a5fe953de730afdd353e2432ace909b0#file-barba-custom-js-L22-L45
barba.init
以外は変更していないため省略。
// 省略(barba.use(barbaPrefetch)より上)
const replaceHeadTags = target => {
const head = document.head
const targetHead = target.html.match(/<head[^>]*>([\s\S.]*)<\/head>/i)[0]
const newPageHead = document.createElement('head')
newPageHead.innerHTML = targetHead
const removeHeadTags = [
"meta[name='keywords']",
"meta[name='description']",
"meta[property^='fb']",
"meta[property^='og']",
"meta[name^='twitter']",
"meta[name='robots']",
'meta[itemprop]',
'link[itemprop]',
"link[rel='prev']",
"link[rel='next']",
"link[rel='canonical']",
].join(',')
const headTags = [...head.querySelectorAll(removeHeadTags)]
headTags.forEach(item => {
head.removeChild(item)
})
const newHeadTags = [...newPageHead.querySelectorAll(removeHeadTags)]
newHeadTags.forEach(item => {
head.appendChild(item)
})
}
barba.init({
transitions: [
{
beforeEnter({ next }) {
replaceHeadTags(next)
}
}
]
})
//省略(const eventDelete = e => {より下)
上記のコードで変更が行えない場合
barba.init({
transitions: [
{
beforeEnter({ next }) {
replaceHeadTags(next)
}
}
]
})
の部分を
barba.hooks.beforeEnter(({ next }) => {
replaceHeadTags(next)
})
に変更。
参考: https://github.com/barbajs/barba/issues/410
transitionのオプションについて
名前 | 説明 |
---|---|
before | 最初 |
beforeLeave | 現在のページを離れる直前 |
leave | 現在のページを離れる時 |
afterLeave | 現在のページを離れた直後 |
beforeEnter | 次のページを表示する直前 |
enter | 次のページを表示する時 |
afterEnter | 次のページが表示された直後 |
after | 最後 |
その他オプションについては https://barba.js.org/docs/advanced/hooks/ 参考。
ページ遷移時にGoogle Analyticsに情報を送信
参考 : https://gist.github.com/mhige/a5fe953de730afdd353e2432ace909b0#file-barba-custom-js-L47-L48
// いろいろ省略
const gaPush = pagename => {
ga('send', 'pageview', pagename)
}
barba.init({
transitions: [
{
beforeEnter({ next }) {
// replaceHeadTags(next)の処理
gaPush(location.pathname)
}
}
]
})
ページ遷移時にページの一番上まで行く。
ページをスクロール → リンククリック → ページ遷移だとスクロールの値が保存されていたので、それを0にする。
// いろいろ省略
barba.hooks.enter(() => {
window.scrollTo(0, 0);
});
参考: https://barba.js.org/docs/advanced/hooks/#Global-hooks
Barbaの範囲外も適応させたい
現状だと header
や footer
などは一切動かないため動きを追加する。(簡単なクラスの付け替えなど)
barba.init({
transitions: [
beforeEnter({ next }) {
const header = document.querySelector('.l-header') // header要素取得
header.classList.toggle('is-active') // クラスの付け替え
// その他いろいろ
}
]
})