WEB制作、マーケティングに関する情報をお届けします。ホームページ制作会社、テラのブログ

非同期通信でシームレスなページ遷移を実現、barba.jsの使い方

タグ:

Webサイトのコンテンツ部分のみを読み込み(切り替え)して滑らかなページ遷移を実現する非同期通信を紹介します。
本記事ではプラグインのbarba.jsを使用します。
実装方法だけでなく非同期通信時に頻繁に問題になりやすいページ遷移先でのjavascriptの不具合にも対応できるように個別のページで実行できるようにしています。また、タイトルやメタタグの書き換えも合わせて実装しております。

コードを紹介

デモのファイル階層

index.html(トップページ)
style.css
main.js
→sample/index.html(サンプルページ)
→function/index.html(ファンクションページ)

上記は自分の環境に合わせて変更してください。

HTML

<!DOCTYPE html>
<html lang="ja">
<head>
    <meta charset="UTF-8">
    <title></title>
    <meta name="description" content="">
    <link rel="stylesheet" href="CSSファイルのディレクトリ/style.css">
    <script src="https://unpkg.com/@barba/core@2"></script>
    <script src="https://cdn.jsdelivr.net/npm/gsap@3.12.5/dist/gsap.min.js"></script>
</head>
<body>
    <header>
        <h1>PJAX / Barba DEMO</h1>
        <nav>
            <li><a href="URL">トップページ</a></li>
            <li><a href="URL/sample/">サンプルページ</a></li>
            <li><a href="URL/function/">ファンクションページ</a></li>
        </nav>
    </header>
    <div class="content">
        <div class="inner">
            <div data-barba="wrapper">
                <div data-barba="container" data-barba-namespace="sample">
                    <h2>サンプルページのコンテンツです</h2>
                    <p>テキストテキストテキストテキストテキストテキストテキストテキストテキストテキストテキストテキストテキストテキストテキストテキストテキストテキストテキストテキストテキストテキストテキストテキストテキストテキストテキストテキストテキストテキストテキストテキストテキストテキストテキストテキストテキストテキストテキストテキストテキストテキストテキストテキストテキストテキストテキストテキストテキストテキストテキストテキストテキストテキストテキストテキストテキストテキストテキストテキストテキストテキストテキストテキストテキストテキストテキストテキストテキストテキストテキストテキストテキストテキストテキストテキストテキストテキストテキストテキスト</p>
                </div>
            </div>
        </div>
    </div>
    <script src="CSSファイルのディレクトリ/main.js"></script>
</body>
</html>

Javascript

document.addEventListener("DOMContentLoaded", function() {
    barba.init({
        transitions: [{
            leave(data) {
                // ページ離脱時のアニメーション
                return gsap.to(data.current.container, {
                    ease: 'power2.InOut',
                    autoAlpha: 0,
                    duration: 0.4,
                    y: 50,
                    height: 0,
                    position: 'absolute',
                });
            },
            enter(data) {
                // ページ到着時のアニメーション
                return gsap.from(data.next.container, {
                    autoAlpha: 0,
                    duration: 0.4,
                    y: 50,
                });
            }
        }],
        views: [
            {
                namespace: 'home',
                beforeEnter(data) {
                    document.title = 'トップ';
                    document.querySelector('meta[name="description"]').setAttribute("content", "このページはトップページです");
                    document.body.className = ''; // すべてのクラスをリセット
                    removeEmptyClass();
                }
            },
            {
                namespace: 'sample',
                beforeEnter(data) {
                    document.title = 'サンプル';
                    document.querySelector('meta[name="description"]').setAttribute("content", "このページはサンプルページです");
                    document.body.className = ''; // すべてのクラスをリセット
                    removeEmptyClass();
                }
            },
            {
                namespace: 'function',
                beforeEnter(data) {
                    document.title = '特定のページ';
                    document.querySelector('meta[name="description"]').setAttribute("content", "このページはjavascriptを実行させているページです");
                    document.body.className = ''; // すべてのクラスをリセット
                    document.body.classList.add('function'); // bodyにfunctionクラスを追加
                },
                afterEnter(data) {
                    // ここにfunctionページのみで実行する処理を記述
                    alert('ファンクションページではjavascriptを実行しています。');
                    removeEmptyClass();
                }
            }
        ]
    });

    // クラスが空の場合、class属性を削除する関数
    function removeEmptyClass() {
        if (document.body.className === '') {
            document.body.removeAttribute('class');
        }
    }
});

コードを解説

HTML

まずはbarba.jsを読み込みます。また、本記事のアニメーションはgsapを使用しておりますのでcdnからgsapも読み込みます。

<script src="https://unpkg.com/@barba/core@2"></script>
<script src="https://cdn.jsdelivr.net/npm/gsap@3.12.5/dist/gsap.min.js"></script>

HTML内の以下の部分がページ遷移時に切り替えられるパーツになります。
『<div data-barba=”container” data-barba-namespace=”home”>』ないにページごとの内容を記入します。

<div data-barba="wrapper">
    <div data-barba="container" data-barba-namespace="home">
        <h2>トップページのコンテンツです</h2>
        <p>テキストテキストテキストテキストテキストテキストテキストテキストテキストテキストテキストテキストテキストテキストテキストテキストテキストテキストテキストテキストテキストテキストテキストテキストテキストテキストテキストテキストテキストテキストテキストテキストテキストテキストテキストテキストテキストテキストテキストテキストテキストテキストテキストテキストテキストテキストテキストテキストテキストテキストテキストテキストテキストテキストテキストテキストテキストテキストテキストテキストテキストテキストテキストテキストテキストテキストテキストテキストテキストテキストテキストテキストテキストテキストテキストテキストテキストテキストテキストテキスト</p>
    </div>
</div>

Javascript

『barba.init({});』でbarba.jsを起動できます。

barba.init({
});

この中に処理を書いていきます。
ページ離脱時と遷移後の動きは『transitions:[{}]』の中に記載していきます。
『leave()』の処理内がページ離脱時のアニメーション、『enter()』の処理内がページ遷移時(到着時)のアニメーションです。
動きはgsapでつけています。こちらの説明は割愛しますがcss3と同じようなものです。

transitions: [{
    leave(data) {
        // ページ離脱時のアニメーション
        return gsap.to(data.current.container, {
            ease: 'power2.InOut',
            autoAlpha: 0,
            duration: 0.4,
            y: 50,
            height: 0,
            position: 'absolute',
        });
    },
    enter(data) {
        // ページ到着時のアニメーション
        return gsap.from(data.next.container, {
            autoAlpha: 0,
            duration: 0.4,
            y: 50,
        });
    }
}],

各ページでタイトルやmetaタグなどの書き換えは『views: [{}]』の中で行います。
また、各ページの指定はhtmlタグに振られている『data-barba-namespace=”○○○○”』の部分と一致しているかを確認して実行されます。
views内で『namespace: ‘○○○○○’』とhtml内の『data-barba-namespace=”○○○○”』で一致した時にそれぞれ実行されます。

タイトルタグなどの書き換え

『document.title = ‘○○’;』はタイトルの書き換え、『document.querySelector(‘meta[name=”description”]’).setAttribute(“content”, “○○○○○○”);』はページ説明の『name=”description”』タグの書き換えです。

特定のページでのjavascriptの実行

functionページではafterEnterを定義してjavascriptを実行しています。
実行内容はbodyにfunctionクラスを追加とアラートを出しています。
このページ毎のjavascriptの実行によって非同期通信におけるページ遷移先での不具合へと対応できます。

views: [
    {
        namespace: 'home',
        beforeEnter(data) {
            document.title = 'トップ';
            document.querySelector('meta[name="description"]').setAttribute("content", "このページはトップページです");
            document.body.className = ''; // すべてのクラスをリセット
            removeEmptyClass();
        }
    },
    {
        namespace: 'sample',
        beforeEnter(data) {
            document.title = 'サンプル';
            document.querySelector('meta[name="description"]').setAttribute("content", "このページはサンプルページです");
            document.body.className = ''; // すべてのクラスをリセット
            removeEmptyClass();
        }
    },
    {
        namespace: 'function',
        beforeEnter(data) {
            document.title = '特定のページ';
            document.querySelector('meta[name="description"]').setAttribute("content", "このページはjavascriptを実行させているページです");
            document.body.className = ''; // すべてのクラスをリセット
            document.body.classList.add('function'); // bodyにfunctionクラスを追加
        },
        afterEnter(data) {
            // ここにfunctionページのみで実行する処理を記述
            alert('ファンクションページではjavascriptを実行しています。');
            removeEmptyClass();
        }
    }
]
クラス削除処理などについて

それぞれのページでの処理に『document.body.className = ”;』がありますが、これはfunctionページでつけたクラス名を除外するためのものです。
また、後に配置している『removeEmptyClass();』ではクラス名がない場合にクラスの属性自体を削除しています。
要はクラスめいがない場合に『body class=””』となってしまうので『body class=””』とするためのものです。

まとめ

barba.jsを使用することで比較的、簡単に導入はできますが一部ページでjavascriptが動かなかったりと普通のサイトを作成するよりは時間がかかります。
ただ、動きが豊富でリッチなサイトを作ることができるためブランディングを重視する場合は重宝します。
ぜひ、参考にしてみてください。

テラ合同会社(東京都)

テラは2014年に東京都でスタートアップしたホームページ制作会社です。ホームページ制作以外にも広告運用、マーケティング、ブランディング、印刷物など幅広い領域をサポートしています。
コーポレートサイトはこちらをご覧ください。