AMPで「ページトップへ遷移する」ボタンを設置する方法
2020-06-11
(LastUpdated: 2020-06-11)
これまでの普通のサイトだったら、何も考えずにjsでサクッと実装できること。 しかし、AMPではすんなり実装ができなかったりします。
それは、AMPはサードパーティーのjsが使えない ためです。 つまり、自分でjsを書くことや、外部ライブラリを読み込んだりすることができません。
「つ、つらい・・・😢」 そんな風なイメージをお持ちの方も、多いのではないでしょうか。
が、心配には及びません。 AMPには、そんな機能を簡単に実装することができる、コンポーネントが用意されています。
この記事では、実装の仕方の解説や、実装中に気になったことをお伝えします。
AMPのオフィシャルでは実装手順を紹介しています。 順に進めていくことで、簡単に実装ができます。 Example: Scroll to top - amp.dev
また、実装サンプルを紹介しているページもあり、これも参考にすると良いです。 AMP Playground
何がいいって、単にコピペをしていけば動くところです。 すでにコンポーネント化されている機能であれば、実に手軽に実装が完了します。
実装時にNuxt.jsでうまく行かなかったHTMLエスケープの問題も、記録しておきます。
AMPサイトで「ページトップへ移動するボタン」を実装する方法
Scroll to Topとは、ページトップへ移動するボタンです。 画面の右下や、左下にあるものです。 様々なサイトで、よく見かけるごく一般的なUIですね。
必ずしも必要なものではないのですが、サイトのデザインによっては、ユーザーの利便性の向上を測ることができます。
UXを考慮して外してみた
このブログでは、一度実装してはみたものの、外しました。 理由はヘッダーが追従してくるので、ユーザーがトップに戻ることで得られるベネフィットが、それほど多くないと判断したからです。 画面の下側にあるということは、スマートフォンでは不用意にタップしてしまう要因にもなり得ることと、文章を読む上で邪魔に感じる場合もあると考えたからです。 (本来ならちゃんとユーザー調査しなければいけませんね)
amp-position-observerとamp-animation、二つのコンポーネントを使う
今回は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専用のコンポーネントゆえに、設定などに手間取らないことです。
また、サンプルもあったりするので、分かりやすい。 こういうところに、実装のハードルを下げようという心意気が伝わってきますね。
いろいろな機能を持ったコンポーネントが、既に用意されています。 これらを活用したら、大概のやりたい事は実現できそうです。