amp-position-observerでスクロール・インタラクションを実装する
2020-06-11
(LastUpdated: 2020-06-11)
スクロールしていると、画像がフェードインしてきたり、画面外から入ってきたりするようなサイト、見たことありますよね。 そんなインタラクションを、かんたんに実現するためのコンポーネントが、AMPには用意されています。
公式ドキュメント amp-position-observer – AMP
あ、そうそう、amp-animationと組み合わせて使うのが基本ですが、ここでは言及しません。 今回は、発火をposition-observer、発火後のインタラクションをanimationで定義、という流れというのを、覚えておいていただければと思います。
[[toc] ## 実装した「おすすめ記事サジェスト」をざっくりと ユーザーが、ある程度のところまでスクロールしたら、画面の下部に、関連記事をサジェストするエリアを表示させます。 とあるゾーンに入ってからの、スクロール量ではなく、指定秒数で表示させるようにしています。
狙い
これによる狙いは、直帰率の低下とページ滞在時間の向上です。 「あ、この記事そんなにおもろくねーや」って思って離脱を考えた頃に、すっと、関連記事の情報をユーザーに提供します。 その結果、ユーザーが関心のあるコンテンツに遷移することができれば、自然と読了率も上がるという仮説です。
ワークフロー
これが機能するまでの大まかなフローはこんな感じ。
- 指定ブロックが表示される
- Amp-position-observerの表示領域に指定ブロックが侵入する
- イベントが発火する
- 指定したamp-animatoinが起動する
指定ブロックが画面内に入ると、イベントを発生させます。 ターゲットとなるブロックのIDも指定することができます。 よって、その指定したブロックが表示されたら、指定のイベントを開始するという制御が可能です。
実装では高さの小さなオブジェクトで試すべき
概ね、実装は簡単です。 試すには、タイトルや一つの画像などで挙動を見るのが良いと思います。 Optionでトリガーのタイミングを細かく設定できます。
ただ、ちょっと理解するのに時間がかかったところがあります。
大きなブロックレベル要素に注意
ビューポートが基本となっていることに、注意を払ってください。 ビューポートというのは、デバイスの画面サイズのなかで、amp-position-observerが機能する範囲(エリア)のことです。
勘違いしていたこと このサイトの記事のブロックのちょうど50%の位置に来たときにトリガーしようと思ってました。 しかし、0.5つまり50%位置でトリガーしてくれるはずが、いくら設定しても上方でトリガーがかかってました。 {.info}
あくまで、「対象のブロックが、ビューポート指定位置に入ってきたらトリガーする」、という点に注意です。
ビューポートの広さはOptionで指定できます。
細かく調整が可能なOption
例えば、このサイトでは以下のように設定を書きます。 ちょっと無理矢理感のある設定もありますが、何かの参考にしていただければと。
/* pugで書いてます */
amp-position-observer(target='story' on='enter:fadeIn.start;exit:fadeOut.start' layout='nodisplay' viewport-margins='0 100vh')
いくつか便利なオプションが用意されており、それで指定していきます。
on
これはクリックなどのイベントと、それにあわせて何をトリガーするのかを指定できます。
layout
amp-position-observerではnodisplayのみ指定できます。
target
表示状態をウォッチする要素のIDを指定します。
指定されていない場合は、<amp-position-observer>
の親要素がターゲットとして使用されます。
intersection-ratios
ビューポートにどれくらいのターゲットを表示してからイベントをトリガーするかを定義します。 値は0と1の間の数値です(デフォルトは0)。
intersection-ratios="0"
Enterは、対象の最初の1ピクセルがビューポートに入ってくると、すぐにトリガします。
Exitは、ターゲットの一番最後のピクセルがビューポートの外に出ると、トリガされます。
intersection-ratios="0.5"
Enterは、目標の50%がビューポートに入ってくるとするとすぐにトリガされます。
Exitは、目標の50%未満がビューポートから出ると、すぐにトリガされます。
intersection-ratios="1"
Enterは、目標が完全に表示されているときにトリガされます。
Exitは、単一のピクセルがビューポートの外に出ると、すぐにトリガされます。
intersection-ratios="0 1"
ターゲットが上端(0が使用される)か下端(1が使用されるか)に応じて条件が異なります。
2つの値(top
bottom
)を指定することによって、トップとボトムに対して異なる比率を指定できます。
viewport-margins
ビューポートの領域を、狭くするために使います。 デフォルトは0で、表示されている画面全体です。 ビューポートの上下にマージンを取ることで、有効範囲を縮めます。 単位はpxとvhが有効です。
2つの値を指定することによって、topとbottomの異なる値を指定することができます。 examples
viewport-margins="100px"
ビューポートを上から100px、下から100px縮小します。viewport-margins="25vh"
ビューポートを上から25%、下から25%縮小します。ビューポートの中央の50%のみを効果的に考慮します。viewport-margins="100px
10vh” ビューポートを上から100px、下から10%縮小することを意味します。
once
トリガーを一度だけの発火にしたい場合に設定します。
まとめ:実装はリファレンスのコピペでOK!
今回はハマってしまったところがありましたが、基本的に導入は簡単です。 コツが掴めるまでいろんなブロックで試すのが良いと思います。
AMPはコンポーネントが使いやすくて、やっぱりメリットがたくさんあります。 Google依存度が高まってしまいますが、それ自体にメリットも含まれているため、乗ってみるのも悪くないと思ってます。