ページ遷移をなくして離脱を防げ! 無限スクロールの活用方法(2/2) 事例詳細|つなweB

[INFINITESCROLL01]無限スクロールを実装する

ここからは、無限スクロールの実装方法について解説する。サンプルは、PCでもスマホでも対応できるようリキッドデザインにし、ページ下までいくと次のコンテンツを読み込むというものだ。なお、誌面の都合でポイントとなる部分のみを解説しているため、詳しくはサンプルファイルを見てほしい。

Ajaxで次のコンテンツを取得する

01 サンプルデータのファイル構造 3つのHTMLファイルを用意し、「コンテンツ1(index.html)→ コンテンツ2(index2.html)→ コンテンツ3(index3.html)」の順番で表示していく

サンプルでは、3つのHTMLを用意した(01)。一つ目のコンテンツ1(index.html)があり、ページ下までスクロールしたら、Ajaxで次ページのコンテンツ2(index2.html)を読み込む(03)。

読み込みが始まったら、あらかじめページの一番下に設置しておいたローディング画像を表示して(A)、読み込み状態であることをユーザーにわかりやすくしておく。

<div class="scroll-content js-scroll-content">
  <div class="js-item-list-wrap">
    <div class="item-list js-item-list"
// ↓--------------------------------------------------↓ B
        data-page="1" 
        data-url="index.html"
        data-prev-url=""
        data-next-url="index2.html">
// ↑--------------------------------------------------↑ B
      <div class="item" data-page-url="index3.html">
        <h2><a href="#">1</a></h2>
      </div>
<!-- 中略 -->
  </div>
  <div class="loading" style="display: none;"><img src="img/loading.gif" alt=""></div>        // A
</div>
02 HTMLの抜粋(sample/scroll/index.html)。data属性で前・次ページのURL情報を持たせている
$.ajax({
  type: 'GET',
  url: next_data_url,
  dataType: 'html',
  success: function (data) {
    $loading.show();                                      // A
    var $itemList = $(data).find('.js-item-list');
    next_data_cache = $itemList;
  },
  complete: function() {
    $loading.hide();
  },
  error: function () {
    $loading.hide();
    alert('通信に失敗しました');
  }
});
03 JavaScriptの抜粋(sample/scroll/js/main.js)。Ajaxでコンテンツを取得する部分のコード

次のコンテンツを事前に読み込む

無限スクロールを実装する際、特に注意すべきなのは、表示スピードだ。せっかく無限スクロールにしても、表示が遅ければ、ユーザーにストレスを与えかねない。逆に言えば、そこを改善すれば、さらにユーザーの離脱率を下げることができる。

そこで今回は、一つ目のコンテンツ1を取得してブラウザに反映させたら、Ajaxですぐに次のコンテンツ2を読み込むようにする。コンテンツ1ではdata属性を使って、次に読み込むコンテンツ2の情報を持たせておく(B)。そして、コンテンツ1がブラウザに反映されたら、data属性の情報を取得し、次に読み込むコンテンツ2のURL情報を使ってAjaxを実行する。このとき、まだコンテンツ2はブラウザには反映させず、読み込んだだけの状態にしておく。そして、ページの一番下までスクロールしたら、コンテンツ2をブラウザに表示させるという仕組みだ(04)。

function showNext(data) {
 $('.js-item-list-wrap').append(data);
 next_data_url = data.data('next-url');
 next_data_cache = false;
 $.ajax({
  type: 'GET',
  url: next_data_url,
  dataType: 'html',
  success: function (data) {
   var $itemList = $(data).find('.js-item-list');
   next_data_cache = $itemList;
  },
  error: function () {
   alert('通信に失敗しました');
  }
 });
};
04 JavaScriptの抜粋(sample/scroll/js/main.js)。事前に読み込んでいた次のコンテンツを表示する部分のコード。「append(data)」の部分でコンテンツがブラウザに追加される

コンテンツ2でも同様の処理を行い、コンテンツ3以降もスムーズに表示できるようにする。このようにコンテンツの取得と表示の処理を分けることで、事前ロードが可能になる。

 

[INFINITESCROLL02]SEOを考慮した無限スクロールにする

無限スクロールを使えばリンクを省略でき、見た目がとてもフラットになり、よりスタイリッシュなデザインを表現できる。では、SEOについてはどうだろうか。ページネーションがないので、検索エンジンが各ページの情報を解析するかどうかは特に気になるところだ。Googleが無限スクロールを実装する上でのベストプラクティス※を公開しているので、その一部を紹介しよう。

JSが無効のブラウザを考慮する

JavaScriptが動かないと、当然、無限スクロールも機能しない。そうなると、次のページへ行く手段がなくなるのでUI的に望ましくない。

そこで、「前ページ」「次ページ」リンクやページネーションを用意し、noscript要素を使用して、JavaScriptが無効時のみ、それらのリンクが表示されるようにしておく(A)。

    <div class="loading" style="display: none;"><img src="img/loading.gif" alt=""></div>
  </div>
// ↓--------------------------------------------------↓ A
<noscript>
    <div class="page-link">
      <span>1</span>
      <a href="index2.html">2</a>
      <a href="index3.html">3</a>
    </div>
  </noscript>
// ↑--------------------------------------------------↑ A
<script src="js/main.js" type="text/javascript"></script>
01 HTMLの抜粋(sample/scroll/index.html)。noscript要素を使って、JavaScript無効時に備える

読み込みに応じてURLを変える

通常、無限スクロールではコンテンツを読み込んだ際にURLは変化しない。そこで、読み込むたびに擬似的にURLを変化させる。

今回は、URLの変更にreplaceStateメソッドを使用する(B)。これはブラウザの履歴には追加せずに、URLの表示だけを変えるものだ。他にpushStateメソッドがあるが、これはブラウザの履歴に追加されるため、ブラウザの「戻る」ボタンを押すと一つ前のURLのスクロール位置に移動してしまう。「戻る」ボタンを押した際のユーザーが期待する挙動は、前ページヘの移動だと思われるので、replaceStateメソッドのほうがいいだろう。

// URLを変えるタイミング
if (Math.abs(scroll_pos - last_scroll) > $window.height() * 0.1) {
  last_scroll = scroll_pos;
  $('.js-item-list').each(function() {
    if (mostlyVisible(this)) {
      history.replaceState(null, null, $(this).attr("data-url"));      // B
      return;
    }
  });
}
02 JavaScriptの抜粋(sample/scroll/js/main.js)。コンテンツ読み込み後にURLを変更する部分のコード。サンプルでは、data属性で設定していたURL情報をもとに「~/index.html」→「~/index2.html」→「~/index3.html」とURLを変えている

rel属性で前後のURLを設定する

インデックスへの登録漏れを防ぐために、各ページのhead要素内にlink要素を使って「rel="next"」と「rel="prev"」を設定し、対応する前後のコンテンツのURLをhref属性に記載する(C)。なお、一つ目のコンテンツの「rel="prev"」、最後のコンテンツの「rel="next"」は必要ない。あくまで前後にコンテンツがある場合のみ記述する。

<head>
  <meta charset="utf-8" />
  <title>Items2</title>
  <script src="https://code.jquery.com/jquery-2.2.0.min.js"></script>
  <link href="css/eric-meyer-reset.css" rel="stylesheet" type="text/css" />
  <link href="css/main.css" rel="stylesheet" type="text/css" />
// ↓--------------------------------------------------↓ C
  <link rel="next" href="index3.html" />
  <link rel="prev" href="index.html" />
// ↑--------------------------------------------------↑ C
</head>
03 HTMLの抜粋(sample/scroll/index2.html)。head要素内でrel属性を使って、コンテンツの前後関係を記述する
04 作成したサンプル
Ajaxを使用しているため、ローカル環境では動作しないこともあるので、サーバにアップロードして確認してほしい

※Googleのウェブマスター向け公式ブログ「検索エンジンとの相性を考慮した無限スクロールのベストプラクティス」 http://googlewebmastercentral-ja.blogspot.jp/2014/02/infinite-scroll-search-friendly.html

 

Text:橋本裕敬
玩具店でマネージャーを経験後、デザイナーとしてWeb制作会社に転職。LINEクリエイターズスタンプなど、Web制作以外のクリエイティブもしつつ、2015年より(株)LIGに入社。 http://liginc.co.jp/
Text:蓮子和也
顔にインパクトがあるフロントエンドエンジニア。アパレル会社でECサイトの運用に携わったのをきっかけにWebデザイナーに転身。大手のサービスの保守運用をメインに行い、数社の制作会社を経て(株)LIGへ参画。LIGでは新規案件を中心にさまざまなUIを実装している。

 

橋本裕敬
※Web Designing 2016年4月号(2016年3月18日発売発売)掲載記事を転載

関連記事