Qiita Teams that are logged in
You are not logged in to any team

Log in to Qiita Team
Community
OrganizationAdvent CalendarQiitadon (β)
Service
Qiita JobsQiita ZineQiita Blog
19
Help us understand the problem. What is going on with this article?
@miwashutaro0611

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

非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') // クラスの付け替え
      // その他いろいろ
    }
  ]
})

参考リンク一覧

19
Help us understand the problem. What is going on with this article?
Why not register and get more from Qiita?
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away

Comments

No comments
Sign up for free and join this conversation.
Sign Up
If you already have a Qiita account Login
19
Help us understand the problem. What is going on with this article?