建立個人化的互動體驗
重要事項:本文件不適用於您目前選取的格式 電子郵件!
本指南概述了可整合至 AMP 網頁的高度個人化互動選項。如同雪花和變數名稱,每個網站都是獨一無二的,而 AMP 的現成元件程式庫可能無法滿足您的所有需求。為此,AMP 提供了可調整的元件,可為複雜的互動需求提供個人化的解決方案。使用這些元件來建立選取介面、顯示小工具,以及處理自訂邏輯。
使用 amp-selector 管理選取狀態
許多常見的網路體驗包括向使用者呈現選項並回應其選取項目。透過 amp-selector
元件,您可以建立選項選單、指定表單輸入行為,以及實作分頁。
amp-selector 提供兩項核心功能
- 根據使用者選取項目更新 UI。
- 管理單一或多個選取狀態。
定義當使用者進行選取時,元素的行為方式,允許單選或多選選項。您可以根據使用者互動停用或醒目提示選取器選項,並公開選取事件,以便與其他 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>
以下範例說明如何將 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>
使用 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>
amp-bind
元件在網頁載入時不會執行評估,但與 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>
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>
這些運算式具有支援函式的允許清單,與傳統 JavaScript 相比,存在些微的差異和限制。如要進一步瞭解運算式,請參閱此處。
定義運算式巨集
您可以重複使用 amp-bind 運算式片段,方法是定義 amp-bind-macro。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>
巨集也可以呼叫在其本身之前定義的其他巨集。巨集無法以遞迴方式呼叫自身。
使用 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-layout
和 amp-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>
-
作者: @CrystalOnScript
貢獻者: @sbenz