建構個人化的互動式體驗
重要事項:本文件不適用於您目前選取的格式 stories!
本指南概述高度個人化的互動性選項,可整合至 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 互動的動作。這支援 Core Web Vitals,因為不會執行可能會拖慢網頁載入速度的計算,並且不允許網頁版面配置偏移,進而提高首次使用者互動的速度。
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-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>
巨集也可以呼叫在其本身之前定義的其他巨集。巨集無法以遞迴方式呼叫自身。
使用 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