web

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

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

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

まさに今回実装するものの、表示結果がここに置かれています。
ちょっと美しくなかったので、一旦、外してます。

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

AMPでは以下ページでの実装例提示しています。
手順そのままに作業をしていくことで、簡単に実装ができます。

特に難しいことはなく、単にコピペをしていけば動くと思います。
めっちゃ簡単ですよね。
なのでここでは、実装の仕方は解説しません

  1. 実装中に気になった AMPコンポーネントについて 調べたこと
  2. Nuxt.jsで実装するときに、htmlのエスケープでハマったこと

上記2つの出来事と、解決方法を書いていきたいと思います。

  1. amp-position-observer
  2. amp-animation
  3. Nuxt.jsでダブルクォートがhtmlエンティティに変換されてしまった
  4. 解決方
  5. まとめ

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-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 フェレット](https://ferret-plus.com/7568)

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

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

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

「jsとcssのどっちが負荷が少ないのか」
そんな風に考えていたのです。
しかし、どちらが正しいみたいなことはないようです。

とりあえずは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>

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

まとめ

これまでの普通のサイトだったら、何も考えずにjsでサクッと実装できてしまいます。
ところが、AMPはjsがほとんど使えません。
自分でjsを書くことや、外部ライブラリを読み込んだりが、ほぼできないのが辛い・・・そんなふうに思っていました。

が!

AMPコンポーネンツで大概のことはできそう

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

実装が簡単

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

また、サンプルもあったりするので、分かりやすく、実装のハードルを下げようとしてくれているところがgood👍

まずは、AMPのドキュメントに書かれているライブラリを理解して、どんな物があるのか知ることから始めようと思いました。
AMPコンポーネントを駆使して、面白い表現で遊んでみたいと思います。

next...
#amp,#nuxt

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

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

構造化データ(JSON-LD)をAMPブログに設置する方法

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

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

サイトのAMP化を検討している方へ、導入前の注意点をまとめました