AMPで「ページトップへ遷移する」ボタンを設置する方法

2020-05-19

(LastUpdated: 2020-05-19)

これまでの普通のサイトだったら、何も考えずにjsでサクッと実装できること。 しかし、AMPではすんなり実装ができなかったりします。

それは、AMPはサードパーティーのjsが使えない ためです。 つまり、自分でjsを書くことや、外部ライブラリを読み込んだりすることができません。

「つ、つらい・・・😢」 そんな風なイメージをお持ちの方も、多いのではないでしょうか。

が、心配には及びません。 AMPには、そんな機能を簡単に実装することができる、コンポーネントが用意されています。

この記事では、実装の仕方の解説や、実装中に気になったことをお伝えします。

AMPのオフィシャルでは実装手順を紹介しています。 順に進めていくことで、簡単に実装ができます。 Example: Scroll to top - amp.dev

また、実装サンプルを紹介しているページもあり、これも参考にすると良いです。 AMP Playground

  1. AMPサイトで「ページトップへ移動するボタン」を実装する方法
  2. amp-position-observerとamp-animation、二つのコンポーネントを使う
  3. まとめ:AMPコンポーネントの実装は超簡単

何がいいって、単にコピペをしていけば動くところです。 すでにコンポーネント化されている機能であれば、実に手軽に実装が完了します。

実装時にNuxt.jsでうまく行かなかったHTMLエスケープの問題も、記録しておきます。

AMPサイトで「ページトップへ移動するボタン」を実装する方法

Scroll to Topとは、ページトップへ移動するボタンです。 画面の右下や、左下にあるものです。 様々なサイトで、よく見かけるごく一般的なUIですね。

必ずしも必要なものではないのですが、サイトのデザインによっては、ユーザーの利便性の向上を測ることができます。

UXを考慮して外してみた

このブログでは、一度実装してはみたものの、外しました。 理由はヘッダーが追従してくるので、ユーザーがトップに戻ることで得られるベネフィットが、それほど多くないと判断したからです。 画面の下側にあるということは、スマートフォンでは不用意にタップしてしまう要因にもなり得ることと、文章を読む上で邪魔に感じる場合もあると考えたからです。 (本来ならちゃんとユーザー調査しなければいけませんね)

amp-position-observerとamp-animation、二つのコンポーネントを使う

AMPのアイコンと文字のブランドマークのブラックバージョン 今回はAMPが用意するコンポーネントを2つ読み込みます。

amp-position-observer

  <script async custom-element="amp-position-observer" src="https://cdn.ampproject.org/v0/amp-position-observer-0.1.js"></script>

amp-position-observerはユーザーの スクロール位置を監視して特定の位置でトリガー させるのに使うコンポーネントです。 スクロールと連動した、Fade-inとかParallaxなどのインタラクションは、amp-fx-collection コンポーネントで実装できます。

amp-animation

間接照明がおしゃれなカフェの画像 `html

`amp-animation`は文字通り、__アニメーションの詳細を制御__ するのに使うコンポーネントです。

__Web Animations API__ を使用してアニメーションを実現しているとのこと。

Web Animations APIがわからないので調べてみました。
[互換性抜群!「Web Animations API」の基本をおさらいしよう|ferret フェレット](https://ferret-plus.com/7568)


現在はjsやらcssやら色んな方法がありすぎるアニメーションの実装に、標準となる仕様を作って、安全かつ効率的に使っていきましょうということでしょうか。

### アニメーションの負荷
そういえばアニメーションを実装するとなると負荷が気になりますね。

「jsとcssのどっちが負荷が少ないのか」
そんな風に考えていたのです。
しかし、どちらが正しいみたいなことはないようです。
[CSS アニメーションと JavaScript のアニメーションの比較  |  Web |  Google Developers](https://developers.google.com/web/fundamentals/design-and-ux/animations/css-vs-javascript?hl=ja)

とりあえずはWeb Animations APIに即した形を目指してみたいと思います。





## Nuxt.jsでダブルクォートがhtmlエンティティに変換されてしまった
![nuxt.js logo image](nuxt.png)

アニメーションを定義する記述をexampleからコピペしました。
```html
  <amp-animation id="showAnim" layout="nodisplay">
    <script type="application/json">
      {
        "duration": "200ms",
        "fill": "both",
        "iterations": "1",
        "direction": "alternate",
        "animations": [{
          "selector": "#scrollToTopButton",
          "keyframes": [{
            "opacity": "1",
            "visibility": "visible"
          }]
        }]
      }
    </script>
  </amp-animation>

このままビルドするとブラウザでエラーが出てしまいました。 原因は、scriptタグの中の、ダブルクォートがHTMLエンティティに自動的に変換 されてしまっていました。 直接書いてしまうと、エスケープする処理が走るようですね。

解決方法

と、いうわけで、この部分の記述を変数に押し込めて、v-htmlで表示させることにしました。 この方法であれば、変数内の文字列はhtmlとしてそのまま吐き出してくれるようです。

~/components/ScrollToTop.vue

<template lang="pug">
  .scroll_to_top
    amp-animation#showAnim(layout='nodisplay')
      script(type="application/json" v-html='show_arrow')

    amp-animation#hideAnim(layout='nodisplay')
      script(type='application/json' v-html="hide_arrow")

    #marker
      amp-position-observer(on='enter:hideAnim.start; exit:showAnim.start', layout='nodisplay')

    button#scrollToTopButton.scrollToTop(on='tap:top-page.scrollTo(duration=200)')

</template>
<script>
  export default {
    data() {
      return {
        show_arrow: '{"duration": "200ms","fill": "both","iterations": "1","direction": "alternate","animations": [{"selector": "#scrollToTopButton","keyframes": [{"opacity": "0.6","visibility": "visible"}]}]}',
        hide_arrow: '{"duration": "200ms","fill": "both","iterations": "1","direction": "alternate","animations": [{"selector": "#scrollToTopButton","keyframes": [{"opacity": "0","visibility": "hidden"}]}]}'
      }
    }
  }
</script>

ちなみに、一つのコンポーネントにまとめても動きました。 ページのどの部分に設置しても、動作させられそうです。

まとめ:AMPコンポーネントの実装は超簡単

フキダシのボードを持った女性ととなりで仕事に専念する男性の画像 AMPコンポーネンツを使うメリットは、簡単さです。 ドキュメント通りにコピペしたら、実装完了してしまう手軽さ。

jQueryを使ったりするより、遥かに楽です。 それは、AMP専用のコンポーネントゆえに、設定などに手間取らないことです。

また、サンプルもあったりするので、分かりやすい。 こういうところに、実装のハードルを下げようという心意気が伝わってきますね。

いろいろな機能を持ったコンポーネントが、既に用意されています。 これらを活用したら、大概のやりたい事は実現できそうです。


タグに関連づけられた記事

AM2

JAMstacなブログにまつわる、技術的なことなどを記録しています。