AMPで「ページトップへ遷移する」ボタンを設置する方法とNuxt.jsでハマったところを解決

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

AMPはサードパーティーのjsがほとんど使えないためです。
つまり、自分でjsを書くことや、外部ライブラリを読み込んだりすることができません。
「つ、つらい・・・😢」
そんなふうに思っていました。

が!

AMPには専用のコンポーネントが用意されています。
これを利用すれば簡単に実装できることがわかりました。

AMP Exampleをコピペして実装をする

AMPサイトで「ページトップへ移動するボタン」を設置します。
様々なサイトで、よく見かけるごく一般的なUIです。

実装の方法は、こちらを参考にしながら進めていきます。
AMP Playground

また、AMPのオフィシャルでは実装例提示しています。
Scroll to top - AMP by Example
手順そのままに作業をしていくことで、簡単に実装ができます。

単にコピペをしていけば動くと思います。

めっちゃ簡単ですよね。
なのでここでは、実装の仕方の解説というよりも、実装中に気になったことや、AMPコンポーネントについて調べたことをまとめたいと思います。

  1. amp-position-observer
  2. amp-animation
  3. Nuxt.jsでダブルクォートがhtmlエンティティに変換されてしまった
  4. 解決方
  5. まとめ:AMPコンポーネンツで大概のことはできそう

ついでにといってはあれですが、実装時にNuxt.jsでうまく行かなかったHTMLエスケープの問題を解決したので、そのことも書いてあります。

AMP Components


今回は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>

☝️訳あって、このsrc=以降のリンクをシングルクォートで囲んでいます。
正式にはダブルクォートになっています 🙏

amp-position-observerはユーザーの スクロール位置を監視して特定の位置でトリガー させるのに使うコンポーネントです。
これ、夢が広がりますよね。
スクロールによる便利なインタラクションが捗りそうです。

そうそう、スクロールによるFade-inとかParallaxとか基本的なインタラクションは、amp-fx-collectionコンポーネントで実装できます。

AMPでfadeやparallaxを簡単に実現できるamp-fx-collectionの使い方
AMPコンポーネントが素晴らしいのは、fadeやparallaxエフェクトが一瞬で実装できちゃうところです。ここではそのやり方をサラリと紹介していきます。...

まずはamp-fx-collectionを見てみることをオススメします。

amp-animation

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

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

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

Web Animations APIがわからないので調べてみました。
互換性抜群!「Web Animations API」の基本をおさらいしよう|ferret フェレット

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

アニメーションによる負荷

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

「jsとcssのどっちが負荷が少ないのか」
そんな風に考えていたのです。
しかし、どちらが正しいみたいなことはないようです。
CSS アニメーションと JavaScript のアニメーションの比較  |  Web  |  Google Developers

とりあえずはWeb Animations APIに集約していく形をとってみたいと思います。

Nuxt.jsでダブルクォートがhtmlエンティティに変換されてしまった

アニメーションを定義する記述をexampleからコピペしました。

<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コンポーネントの実装は素人でもできるくらい簡単

AMPコンポーネントの特徴は、実装が非常に簡単でスムーズ
UIに関する部分などは、ドキュメント通りにコピペしたら、普通に動くことが多いです。
jQueryを使ったりして自分で書いていた頃よりは、遥かに楽ができそうです。

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

まずは、AMPのドキュメントに書かれているライブラリを理解して、どんな物があるのか見るのも楽しそうです。
どんなことが実現できるのか、夢が膨らみます😄

the next
#amp,#nuxt

AMPでスクロール・インタラクションを実装したのでamp-position-observerについてまとめる。

AMPを最適化して更に高速化する!

ブログ評価ツールLighthouseを使ってUXを向上させる

サイトのAMP化を検討している方へ導入によるメリットとそうじゃない部分を解説します

3分でOK!AMPサイトにfacebookプラグインでコメント欄を設置する

AMPでfadeやparallaxを簡単に実現できるamp-fx-collectionの使い方

Google Fonts+日本語をAMPサイトに導入する

AMPサイトでgoogle analyticsを設置する方法