LoginSignup
25
24

More than 3 years have passed since last update.

Barba.js(v2)を使ってネイティブ風な動きを実装する

Last updated at Posted at 2019-12-06

非SPAのサイトでネイティブ風な動きを実装したいと思い、Barba.jsを使ったので、その時に対応したことなどメモ。

完成したもの

gifなので、速度は結構早いですが、、、

barba動き.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の範囲外も適応させたい

現状だと headerfooterなどは一切動かないため動きを追加する。(簡単なクラスの付け替えなど)

barba.init({
  transitions: [
    beforeEnter({ next }) {
      const header = document.querySelector('.l-header') // header要素取得
      header.classList.toggle('is-active') // クラスの付け替え
      // その他いろいろ
    }
  ]
})

参考リンク一覧

25
24
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
25
24