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 中的用戶端算繪,深入瞭解如何使用 amp-list 在頁面載入時評估狀態。

相反地,它會等到使用者觸發與 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-macro 來重複使用 amp-bind 表達式片段。amp-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 中開啟此程式碼片段