AMP

建立個人化的互動體驗

重要事項:本文件不適用於您目前選取的格式 電子郵件

本指南概述了可整合至 AMP 網頁的高度個人化互動選項。如同雪花和變數名稱,每個網站都是獨一無二的,而 AMP 的現成元件程式庫可能無法滿足您的所有需求。為此,AMP 提供了可調整的元件,可為複雜的互動需求提供個人化的解決方案。使用這些元件來建立選取介面、顯示小工具,以及處理自訂邏輯。

使用 amp-selector 管理選取狀態

許多常見的網路體驗包括向使用者呈現選項並回應其選取項目。透過 amp-selector 元件,您可以建立選項選單、指定表單輸入行為,以及實作分頁。

amp-selector 提供兩項核心功能

  1. 根據使用者選取項目更新 UI。
  2. 管理單一或多個選取狀態。

定義當使用者進行選取時,元素的行為方式,允許單選或多選選項。您可以根據使用者互動停用或醒目提示選取器選項,並公開選取事件,以便與其他 AMP 元件互動。

<amp-selector layout="container"
  class="sample-selector"
  multiple>
  <amp-img src="/static/samples/img/landscape_sea_300x199.jpg"
    width="90"
    height="60"
    option="1"
    alt="Photo of a sea landscape"></amp-img>
  <amp-img src="/static/samples/img/landscape_desert_300x200.jpg"
    width="90"
    height="60"
    option="2"
    selected
    alt="Photo of a desert landscape"></amp-img>
  <amp-img src="/static/samples/img/landscape_ship_300x200.jpg"
    width="90"
    height="60"
    option="3"
    alt="Photo of a water landscape with ship"></amp-img>
  <amp-img src="/static/samples/img/landscape_village_300x200.jpg"
    width="90"
    height="60"
    option="4"
    disabled
    alt="Photo of a village landscape"></amp-img>
</amp-selector>
在 playground 中開啟此程式碼片段

以下範例說明如何將 amp-selector 與 SVG 結合,以建立互動式圖表。

<head>
  <style amp-custom>
    .bar[option][selected] {
      fill: red;
      outline: none;
    }
  </style>
</head>
<body>
  <amp-selector>
    <svg class="chart" width="420" height="150" aria-labelledby="title desc" role="img">
      <title id="title">A bar chart showing information</title>
      <desc id="desc">4 apples; 8 bananas; 15 kiwis; 16 oranges; 23 lemons</desc>
      <g class="bar" option>
        <rect width="40" height="19"></rect>
        <text x="45" y="9.5" dy=".35em">4 apples</text>
      </g>
      <g class="bar" option>
        <rect width="80" height="19" y="20"></rect>
        <text x="85" y="28" dy=".35em">8 bananas</text>
      </g>
      <g class="bar" option>
        <rect width="150" height="19" y="40"></rect>
        <text x="150" y="48" dy=".35em">15 kiwis</text>
      </g>
      <g class="bar" option selected>
        <rect width="160" height="19" y="60"></rect>
        <text x="161" y="68" dy=".35em">16 oranges</text>
      </g>
      <g class="bar" option>
        <rect width="230" height="19" y="80"></rect>
        <text x="235" y="88" dy=".35em">23 lemons</text>
      </g>
    </svg>
  </amp-selector>
</body>
在 playground 中開啟此程式碼片段

使用 amp-bind 進行簡單的互動和資料繫結

使用者期望現代網路能對其互動做出反應,並反映他們所做的變更。amp-bind 元件可啟用狀態設定、讀取、UI 變更,並可處理使用者輸入和簡單邏輯。

<amp-state id="foo">
  <script type="application/json">
    {
        "bar": "State is set."
    }
  </script>
</amp-state>
<p [text]="foo.bar">No state is set</p>
<button on="tap:AMP.setState({})">Set State</button>
在 playground 中開啟此程式碼片段

amp-bind 元件在網頁載入時不會執行評估,但與 amp-list 結合時除外。

如要進一步瞭解如何在網頁載入時使用 amp-list 評估狀態,請參閱「AMP 中的用戶端轉譯」。

相反地,它會等到使用者觸發與 amp-bind 互動的動作。這支援核心網路指標,因為它不會執行會減慢網頁載入速度的計算,並禁止網頁版面配置位移,進而提高首次使用者互動的速度。

amp-bind 使用自己的語法來建立互動性並繫結元素。它運用了三個主要概念:狀態、運算式和繫結。

繫結

繫結是特殊的屬性,可將元素屬性連結至運算式,進而將所有項目整合在一起。繫結是 [property] 格式的特殊屬性。這會將元素屬性連結至狀態。使用繫結來更新文字、變更圖片大小,或允許使用者指定外觀。

如要進一步瞭解繫結,以及查看 AMP 元件HTML 元素的可繫結屬性完整清單,請參閱此處。

狀態

每個使用 amp-bind 的 AMP 網頁都有自己的作用域、可變 JSON 資料,大小限制為 100kb。此資料即為狀態。

<amp-state id="todos">
    <script type="application/json">
      [
        "Learn AMP"
      ]
    </script>
  </amp-state>

  <input id="todoInput" type="text" on="input-throttled:AMP.setState({
                           newTodo: event.value
                         })">
  <button on="tap:AMP.setState({
                todos: todos.concat(newTodo)
              })">
    Add Todo
  </button>
 <amp-list [src]="todos" src="amp-state:todos" height="20" items="." [is-layout-container]=true>
<template type="amp-mustache">
      <li>{{.}}</li>
    </template>  </amp-list>
在 playground 中開啟此程式碼片段

amp-bind 支援預先定義的狀態、使用者互動後的狀態初始化,以及狀態更新。您可以使用運算式、繫結、動作和事件來參照、新增或變更任何定義為鍵值組的變數。

有多種方法可以宣告和使用狀態。如要進一步瞭解狀態,請參閱 amp-bind 文件

運算式

amp-bind 元件使用類似 JavaScript 的運算式,對使用者輸入和狀態變數中的資料執行運算。

<p [text]="myExpressionsState.foo"></p>
<!-- 1 + '1'; // 11 -->
<button on="tap:AMP.setState({myExpressionsState: {foo: 1 + '1'}})">
  foo: 1 + "1"
</button>
<!-- 1 + +'1'; // 2 -->
<button on="tap:AMP.setState({myExpressionsState: {foo: 1 + + '1'}})">
  foo: 1 + + "1"
</button>
<!-- !0; // true -->
<button on="tap:AMP.setState({myExpressionsState: {foo: !0}})">foo: !0</button>
<!-- null || 'default'; // 'default' -->
<button on="tap:AMP.setState({myExpressionsState: {foo: null || 'default'}})">
  null || "default"
</button>
<!-- [1, 2, 3].map(x => x + 1); // 2,3,4 -->
<button
  on="tap:AMP.setState({myExpressionsState: {foo: [1, 2, 3].map(x => x + 1)}})"
>
  [1, 2, 3].map(x => x + 1)
</button>
在 playground 中開啟此程式碼片段

這些運算式具有支援函式的允許清單,與傳統 JavaScript 相比,存在些微的差異和限制。如要進一步瞭解運算式,請參閱此處。

運算式很快就會變得難以維護。請務必保持簡潔,並使用 amp-bind-macro 和 amp-action-macro 來封裝常見邏輯。

定義運算式巨集

您可以重複使用 amp-bind 運算式片段,方法是定義 amp-bind-macroamp-bind-macro 元素允許運算式採用零或多個引數,並參照目前狀態。像函式一樣叫用 amp-bind-macro,從文件中的任何位置參照 id 屬性值。

<amp-bind-macro
  id="circleArea"
  arguments="radius"
  expression="3.14 * radius * radius"
></amp-bind-macro>
<p>
  Input a radius value
</p>
<input
  type="number"
  min="0"
  max="100"
  value="0"
  on="input-throttled:AMP.setState({myCircle:{radius: event.value}})"
/>
<p>
  The circle has an area of
  <span [text]="circleArea(myCircle.radius)">0</span>.
</p>
在 playground 中開啟此程式碼片段

巨集也可以呼叫在其本身之前定義的其他巨集。巨集無法以遞迴方式呼叫自身。

使用 amp-script 進行複雜的互動

部分體驗需要高度複雜的解決方案和自訂邏輯。在這些情況下,請使用 amp-script 元件將功能嵌入您的 AMP 網頁中。您可以編寫原生 JavaScript,或匯入 Preact 等程式庫,所有這些都不會犧牲效能。使用它來操作 DOM 或匯入個人化小工具。

amp-script 對每個網頁上的自訂 JavaScript 有 150 KB 的限制,在 <amp-script> 的每個執行個體之間共用。它具有 API 允許清單和一些安全性功能,請務必注意。

建立自訂小工具

我們相信網路應是令人愉悅、身歷其境且獨一無二的。獨特的網站將需要與其品牌相符的功能和風格。透過 amp-script,您可以在網頁中的任何位置匯入自訂小工具。使用這些小工具來建立美觀的介面,這些介面可在以原生 JavaScript、Preact 或您需要的任何程式碼編寫的複雜邏輯上執行。請在此處查看 Worker DOM Preact 示範

使用狀態管理複雜的互動

您可能需要執行複雜的計算,或從變更 DOM 的基礎邏輯中擷取和處理資訊。您可以透過將整個網頁包裝在 amp-script 元素中來管理此邏輯,但這樣做會失去 AMP 的部分優勢。如要保留這些優勢,您可以將複雜的計算卸載到 amp-script,然後將其與 amp-bind 結合,以更新和反映新狀態。

在 amp-script 中實作所有互動

在某些情況下,將整個網頁包裝在 <amp-script> 中是建立具有 AMP 的高度互動式體驗的最佳方式。

雖然此解決方案可讓您完全掌控網頁,但它確實會移除 AMP 提供的一些優勢。例如,建立新的 AMP 元件。amp-script 元件可以將任何 HTML 元素新增至網頁 DOM,但僅限於 amp-layoutamp-img 元件。

合併 amp-script 和 amp-bind

amp-script 元件可讓您實作複雜的網域邏輯,這會導致 amp-bind 運算式變得過於複雜。您可以將邏輯卸載到 amp-script,並使用 amp-bind 更新具有結果的網頁狀態,而無需將整個網頁包裝在 <amp-script> 標記中。有一個注意事項,使用者必須與觸發計算的元素互動。但是,一旦資訊經過處理,amp-script 就可以透過呼叫 AMP.setState 自行更新網頁的狀態。amp-bind 的強大功能將處理其餘部分以更新 DOM。

<head>
  <meta
    name="amp-script-src"
    content="sha384-qdYQLoj2SRKXBu33BwIoyRKorw0b0nQ8UPIoIMc9wL8KVLcKODSAK52yNGQNS_vN"
  />
  <style amp-custom>
    .clickedButton {
      border: 5px solid green;
    }
  </style>
</head>
<body>
  <amp-script width="200" height="100" script="hello-world" [class]="scriptStyle">
    <button>Hello amp-script!</button>
  </amp-script>
  <script id="hello-world" type="text/plain" target="amp-script">
    const btn = document.querySelector('button');
    btn.addEventListener('click', () => {
      document.body.textContent = 'Hello World!';
      AMP.setState({ scriptStyle: "clickedButton" })
    });
  </script>
</body>
在 playground 中開啟此程式碼片段