amp-list
描述
動態下載資料並使用範本建立列表項目。
必要指令碼
<script async custom-element="amp-list" src="https://cdn.ampproject.org/v0/amp-list-1.0.js"></script>
範例
用法
amp-list
元件會從 CORS JSON 端點擷取動態內容。端點的回應包含資料,這些資料會在指定的範本中呈現。
您可以透過兩種方式指定範本
template
屬性,參照現有範本元素的 ID。- 直接巢狀於
amp-list
元素內的範本元素。
<amp-form>
) 使用 <amp-list>
時,請注意,範本可能無法在有效的 AMP 文件中巢狀。在這種情況下,有效的解決方法是透過 template
屬性依 id
提供範本。進一步瞭解 <amp-mustache>
中的巢狀範本。如需範本的詳細資訊,請參閱 AMP HTML 範本。
顯示動態列表
在以下範例中,我們擷取包含網址和標題的 JSON 資料,並在巢狀 amp-mustache 範本中呈現內容。
<amp-list width="auto" height="100" layout="fixed-height" src="/static/inline-examples/data/amp-list-urls.json" > <template type="amp-mustache"> <div class="url-entry"> <a href="{{url}}">{{title}}</a> </div> </template> </amp-list>
以下是我們使用的 JSON 檔案
{ "items": [ { "title": "AMP YouTube Channel", "url": "https://www.youtube.com/channel/UCXPBsjgKKG2HqsKBhWA4uQw" }, { "title": "AMPproject.org", "url": "https://www.ampproject.org/" }, { "title": "AMP", "url": "https://amp.dev.org.tw/" }, { "title": "AMP Start", "url": "https://ampstart.com/" } ] }
以下是我們如何設定擷取內容的樣式
amp-list div[role='list'] { display: grid; grid-gap: 0.5em; }
要求一律從用戶端發出,即使文件是從 AMP 快取提供也一樣。載入會根據元素與目前檢視區的距離,使用一般的 AMP 規則觸發。
如果 <amp-list>
在載入後需要更多空間,它會要求 AMP 執行階段使用一般的 AMP 流程更新其高度。如果 AMP 執行階段無法滿足新高度的要求,則會在可用的情況下顯示 overflow
元素。但是請注意,<amp-list>
元素在文件底部的典型放置位置幾乎總是保證 AMP 執行階段可以調整它們的大小。
amp-list
的無障礙考量
預設情況下,<amp-list>
會將 list
ARIA 角色新增至列表元素,並將 listitem
角色新增至透過範本呈現的項目元素。如果列表元素或其任何子項不是「可使用 Tab 鍵選取的」(可透過鍵盤按鍵 (例如 a
和 button
元素,或任何具有正 tabindex
的元素) 存取),則預設會將 tabindex
0
新增至列表項目。這種行為並非總是適當的 - 一般來說,只有互動式控制項/內容才應該可聚焦。如果您想要禁止此行為,請務必在範本的最外層元素中包含 tabindex="-1"
。
aria-live="polite"
),這表示列表內容的任何變更都會導致輔助技術 (例如螢幕閱讀器) 讀出/宣告整個列表。由於列表最初呈現的方式,這也可能導致在頁面載入時宣告整個列表。為了暫時解決這個問題,您可以將 aria-live="off"
新增至 <amp-list>
,這將覆寫 aria-live="polite"
的新增。
<template type="amp-mustache"> <div class="item">{{item}}</div> <div class="price">{{price}}</div> </template>
如果改為以下方式提供,則最可預測地套用和呈現
<template type="amp-mustache"> <div> <div class="item">{{item}}</div> <div class="price">{{price}}</div> </div> </template>
XHR 批次處理
AMP 會批次處理對 JSON 端點的 XMLHttpRequests (XHR),也就是說,您可以使用單一 JSON 資料要求作為 AMP 頁面上多個消費者 (例如,多個 <amp-list>
元素) 的資料來源。例如,如果您的 <amp-list>
對端點發出 XHR,當 XHR 正在傳輸時,所有後續對相同端點的 XHR 都不會觸發,而是會傳回第一個 XHR 的結果。
在 <amp-list>
中,您可以使用 items
屬性來呈現 JSON 回應的子集,讓您有多個 <amp-list>
元素呈現不同的內容,但共用單一 XHR。
指定溢位
或者,<amp-list>
元件可以包含具有 overflow
屬性的元素。如果符合以下所有條件,AMP 將顯示此元素
- 呈現到
amp-list
中的內容超過其指定的尺寸。 amp-list
的底部在檢視區內。amp-list
的底部不在頁面底部附近 (定義為文件底部 15% 或底部 1000 像素的最小值)
如果 amp-list
在檢視區外,它將自動展開。
範例:當列表需要更多空間時顯示溢位
在以下範例中,我們顯示影像和標題的列表。由於 <amp-list>
內容需要比可用空間更多的空間,因此 AMP 框架會顯示溢位元素。
<amp-list width="auto" height="140" layout="fixed-height" src="/static/inline-examples/data/amp-list-data.json" > <template type="amp-mustache"> <div class="image-entry"> <amp-img src="{{imageUrl}}" width="100" height="75"></amp-img> <span class="image-title">{{title}}</span> </div> </template> <div overflow class="list-overflow" style="background-color:red;"> See more </div> </amp-list>
AMP 將以下 CSS 套用至具有 overflow
屬性的元素
.list-overflow[overflow] { position: absolute; bottom: 0; left: 0; right: 0; }
預留位置和後備
或者,<amp-list>
支援預留位置和/或後備。
- 預留位置是具有
placeholder
屬性的子元素。此元素會顯示,直到<amp-list>
成功載入為止。如果也提供後備,則當<amp-list>
載入失敗時,預留位置會隱藏。 - 後備是具有
fallback
屬性的子元素。如果<amp-list>
載入失敗,則會顯示此元素。
在 預留位置和後備 中瞭解更多資訊。請注意,子元素不能同時是預留位置和後備。
<amp-list src="https://foo.com/list.json"> <div placeholder>Loading ...</div> <div fallback>Failed to load data.</div> </amp-list>
重新整理資料
<amp-list>
元素公開 refresh
動作,其他元素可以在 on="tap:..."
屬性中參照該動作。
<button on="tap:myList.refresh">Refresh List</button> <amp-list id="myList" src="https://foo.com/list.json"> <template type="amp-mustache"> <div>{{title}}</div> </template> </amp-list>
動態調整大小
在某些情況下,我們可能需要 <amp-list>
在使用者互動時調整大小。例如,當 <amp-list>
包含使用者可能點擊的 amp-accordion 時,當 <amp-list>
的內容由於繫結的 CSS 類別而變更大小時,或者當 <amp-list>
內的項目數量由於繫結的 [src]
屬性而變更時。changeToLayoutContainer
動作透過在觸發此動作時將 amp list 變更為 layout="CONTAINER"
來處理此問題。請參閱以下範例
<button on="tap:list.changeToLayoutContainer()">Show Grid</button> <amp-list id="list" width="396" height="80" layout="responsive" src="/test/manual/amp-list-data.json?RANDOM" > <template type="amp-mustache"> {{title}} </template> </amp-list>
從 amp-state 初始化
在大多數情況下,您可能需要 <amp-list>
從伺服器要求 JSON。但是 <amp-list>
也可以使用您包含在 <amp-state>
中的 JSON,就在您的 HTML 中!這表示呈現可以無需額外的伺服器呼叫即可發生,當然,如果您的頁面是從 AMP 快取提供的,則資料可能不是最新的。
以下是如何讓 <amp-list>
從 <amp-state>
呈現
- 將 amp-bind 指令碼新增至您文件的
<head>
。 - 在您的
<amp-list>
的 src 屬性中使用amp-state:
通訊協定,如下所示:<amp-list src="amp-state:localState">
請注意,無論 JSON 是從您的伺服器要求還是從狀態變數提取,<amp-list>
都以相同的方式處理 JSON。所需的格式不會變更。
請參閱下方的完整範例,
<amp-state id="localState"> <script type="application/json"> { "items": [{"id": 1}, {"id": 2}, {"id": 2}] } </script> </amp-state> <amp-list src="amp-state:localState"> <template type="amp-mustache"> <li>{{id}}</li> </template> </amp-list>
使用 amp-script 作為資料來源
您可以將匯出的 <amp-script>
函式用作 <amp-list>
的資料來源。這讓您可以彈性地組合和轉換伺服器回應,然後再交給 <amp-list>
。所需的格式是 <amp-script>
ID 和函式名稱,以句點分隔,例如 amp-script:id.functionName
。
請參閱下方的範例
<!-- See the [amp-script](https://amp.dev.org.tw/documentation/components/amp-script/) documentation to setup the component and export your function> --> <amp-script id="dataFunctions" script="local-script" nodom></amp-script> <script id="local-script" type="text/plain" target="amp-script"> function getRemoteData() { return fetch('https://example.com') .then(resp => resp.json()) .then(transformData) } exportFunction('getRemoteData', getRemoteData); </script> <!-- "exported-functions" is the <amp-script> id, and "getRemoteData" corresponds to the exported function. --> <amp-list id="amp-list" width="auto" height="100" layout="fixed-height" src="amp-script:dataFunctions.getRemoteData" > <template type="amp-mustache"> <div>{{.}}</div> </template> </amp-list>
載入更多和無限捲動
load-more
屬性具有 manual
和 auto
選項,允許分頁和無限捲動。
<amp-list load-more="auto" src="https://my.rest.endpoint/" width="100" height="200" > <template type="amp-mustache"> // ... </template> </amp-list>
如需運作範例,請參閱 test/manual/amp-list/infinite-scroll-1.amp.html 和 test/manual/amp-list/infinite-scroll-2.amp.html。
當使用 <amp-list>
無限捲動時,元件下方放置的內容可能無法存取,建議將無限捲動內容放置在文件底部。
當結合 <amp-analytics>
捲動觸發器使用 <amp-list>
無限捲動時,建議使用 <amp-analytics>
的 useInitialPageSize
屬性,以更準確地測量捲動位置,而忽略 <amp-list>
造成的高度變更。
如果沒有 useInitialPageSize
,則 100%
捲動觸發點可能永遠不會觸發,因為會載入更多文件。請注意,這也會忽略其他擴充功能 (例如展開內嵌內容) 造成的大小變更,因此某些捲動事件可能會過早觸發。
自訂載入更多元素
具有 load-more
屬性的 <amp-list>
包含以下 UI 元素:載入更多按鈕、載入器、載入失敗元素,以及選擇性地標記列表結尾的結束帽。這些元素可以透過提供 <amp-list-load-more>
元素作為具有以下屬性的 <amp-list>
子項進行自訂
load-more-button
具有 load-more-button
屬性的 <amp-list-load-more>
元素,如果還有更多元素要載入,則會在列表結尾顯示 (適用於手動載入更多)。按一下此元素將觸發擷取,以從 load-more-src
欄位或與 load-more-bookmark
屬性對應的傳回資料欄位載入更多元素。此元素可以透過提供具有屬性 load-more-button
的子元素來進行自訂 <amp-list>
。
無限捲動列表的無障礙考量
使用無限捲動列表時請小心 - 如果列表後方有任何內容 (包括標準頁尾或類似內容),使用者將無法存取它,直到所有列表項目都已載入/顯示。這可能會使體驗令人沮喪,甚至讓使用者無法克服。請參閱 Adrian Roselli:所以您認為您建立了良好的無限捲動。
範例
<amp-list load-more="manual" src="https://www.load.more.example.com/" width="400" height="800" > ... <amp-list-load-more load-more-button> <!-- My custom see more button --> <button>See More</button> </amp-list-load-more> </amp-list>
它可以透過 amp-mustache
範本化。
範例
<amp-list load-more="auto" width="100" height="500" src="https://www.load.more.example.com/" > ... <amp-list-load-more load-more-button> <template type="amp-mustache"> Showing {{#count}} out of {{#total}} items <button>Click here to see more!</button> </template> </amp-list-load-more> </amp-list>
load-more-loading
此元素是一個載入器,如果使用者到達列表結尾且內容仍在載入中,或者由於按一下 load-more-button
元素 (當 <amp-list>
的新子項仍在載入時) 而顯示。此元素可以透過提供具有屬性 load-more-loading
的子元素來進行自訂 <amp-list>
。以下範例
<amp-list load-more="auto" src="https://www.load.more.example.com/" width="400" height="800" > ... <amp-list-load-more load-more-loading> <!-- My custom loader --> <svg>...</svg> </amp-list-load-more> </amp-list>
load-more-failed
包含 load-more-failed
屬性的 <amp-list-load-more>
元素,其中包含具有 load-more-clickable
屬性的按鈕,如果載入失敗,則會在 <amp-list>
底部顯示。按一下此元素將觸發重新載入失敗的網址。此元素可以透過提供具有屬性 load-more-failed
的子元素來進行自訂 <amp-list>
。以下範例
<amp-list load-more="auto" src="https://www.load.more.example.com/" width="200" height="500" > ... <amp-list-load-more load-more-failed> <button>Unable to Load More</button> </amp-list-load-more> </amp-list>
在以上範例中,整個 load-more-failed
元素都是可點擊的。但是,此元素的常見模式是包含可點擊「重新載入」按鈕的一般不可點擊「載入失敗」元素。為了說明這一點,您可以擁有一個通常不可點擊的元素,其中包含一個具有 load-more-clickable
元素的按鈕。例如
<amp-list load-more="auto" src="https://www.load.more.example.com/" width="200" height="500" > ... <amp-list-load-more load-more-failed> <div> Here is some unclickable text saying sorry loading failed. </div> <button load-more-clickable>Click me to reload!</button> </amp-list-load-more> </amp-list>
load-more-end
預設情況下不提供此元素,但如果包含 load-more-end
屬性的 <amp-list-load-more>
元素作為子元素附加到 <amp-list>
,如果沒有更多項目,則此元素將顯示在 <amp-list>
底部。此元素可以透過 amp-mustache
範本化。以下範例
<amp-list load-more="auto" src="https://www.load.more.example.com/" width="200" height="500" > ... <amp-list-load-more load-more-end> <!-- Custom load-end element --> Congratulations! You've reached the end. </amp-list-load-more> </amp-list>
替換
<amp-list>
允許所有標準網址變數替換。請參閱 替換指南 以取得更多資訊。
例如
<amp-list src="https://foo.com/list.json?RANDOM"></amp-list>
可能會向類似 https://foo.com/list.json?0.8390278471201
的網址發出要求,其中 RANDOM 值在每次曝光時隨機產生。
屬性
src
(必填)
遠端端點的網址,該端點傳回將在此 <amp-list>
中呈現的 JSON。src
屬性有三種有效的通訊協定。
- https:這必須參照 CORS HTTP 服務。不支援不安全的 HTTP。
- amp-state:用於從
<amp-state>
資料初始化。請參閱 從<amp-state>
初始化 以取得更多詳細資訊。 - amp-script:用於將
<amp-script>
函式用作資料來源。請參閱 使用<amp-script>
作為資料來源 以取得更多詳細資訊。
如果擷取 src
網址的資料失敗,<amp-list>
會觸發低信任 fetch-error
事件。
如果存在 [src]
屬性,則可以省略 src
屬性。[src]
支援網址和非網址運算式值;請參閱 amp-bind
元素特定屬性文件 中的 amp-list
以取得詳細資訊。
credentials
定義 Fetch API 指定的 credentials
選項。
- 支援的值:
omit
、include
- 預設值:
omit
若要傳送憑證,請傳遞 include
的值。如果設定此值,則回應必須遵循 AMP CORS 安全性指南。
以下範例指定包含憑證以在列表中顯示個人化內容
<amp-list credentials="include" src="<%host%>/json/product.json?clientId=CLIENT_ID(myCookieId)" > <template type="amp-mustache"> Your personal offer: ${{price}} </template> </amp-list>
items
定義運算式以尋找要在回應中呈現的陣列。這是一個點表示法運算式,透過 JSON 回應的欄位導覽。依預設,<amp-list>
預期一個陣列,可以使用 single-item
屬性從物件載入資料。
- 預設值為
"items"
。預期的回應:{items: [...]}
。 - 如果回應本身是所需的陣列,請使用值
"."
。預期的回應為:[...]
。 - 允許巢狀導覽 (例如,
"field1.field2"
)。預期的回應為:{field1: {field2: [...]}}
。
當指定 items="items"
時 (這是預設值),回應必須是包含名為 "items"
的陣列屬性的 JSON 物件
{ "items": [...] }
max-items
整數值,指定要呈現的項目陣列的最大長度。如果傳回的值超過 max-items
,則 items
陣列將截斷為 max-items
項目。
single-item
使 <amp-list>
將傳回的結果視為單一元素陣列。物件回應將包裝在陣列中,因此 {items: {...}}
的行為就像 {items: [{...}]}
一樣。
xssi-prefix
使 <amp-list>
在剖析之前從擷取的 JSON 中剝離前置字串。這對於包含 安全性前置字串 (例如 )]}
) 的 API 很有用,以協助防止跨網站指令碼攻擊。
例如,假設我們有一個 API 傳回此回應
)]}{ "items": ["value"] }
我們可以指示 amp-list 移除安全性前置字串,如下所示
<amp-list xssi-prefix=")]}" src="https://foo.com/list.json"></amp-list>
reset-on-refresh
當列表的來源透過 amp-bind
或 refresh()
動作重新整理時,再次顯示載入指示器和預留位置。
依預設,這只會在導致網路擷取的重新整理時觸發。若要在所有重新整理時重設,請使用 reset-on-refresh="always"
。
binding
對於也使用 amp-bind
的 <amp-list>
頁面,控制是否封鎖呈現已呈現子項中繫結 (例如 [text]
) 的評估。
我們建議使用 binding="no"
或 binding="refresh"
以獲得更快的效能。
binding="no"
:永不封鎖呈現(最快)。binding="refresh"
:初始載入時不封鎖呈現(更快)。binding="always"
:始終封鎖呈現(慢)。
如果未提供 binding
屬性,則預設值為 always
。
[is-layout-container]
這是一個可繫結的屬性,依預設應始終為 false
。當透過 amp-bind
設定為 true
時,它會將 <amp-list>
的版面配置變更為 container
。此屬性對於處理 amp-list 的動態調整大小很有用。
由於 <amp-list>
不支援版面配置 CONTAINER
的相同原因,因此此屬性依預設不能為 true — 它可能會在首次載入時導致內容跳動。
或者,也可以使用 changeToLayoutContainer
動作。
load-more
此屬性接受兩個值:「auto」或「manual」。將此屬性的值設定為「manual」將在 <amp-list>
結尾顯示「載入更多」按鈕。將此屬性的值設定為「auto」將導致 <amp-list>
自動載入更多元素,向下三個檢視區以獲得無限捲動效果。
load-more-bookmark
此屬性指定傳回資料中的欄位名稱,該欄位名稱將提供要載入的下一個項目的網址。如果未指定此屬性,<amp-list>
預期 json 酬載具有 load-more-src
欄位,該欄位對應於下一個要載入的網址。如果此欄位被呼叫為其他名稱,您可以透過 load-more-bookmark
欄位指定該欄位的名稱。例如,在以下範例酬載中,我們將指定 load-more-bookmark="next"
。
{ "items": [...], "next": "https://url.to.load" }
通用屬性
此元素包含 通用屬性 延伸至 AMP 元件。
驗證
請參閱 AMP 驗證器規格中的 amp-list 規則。
您已閱讀本文檔十幾次,但它並沒有真正涵蓋您的所有問題?也許其他人也有同樣的感覺:在 Stack Overflow 上與他們聯繫。
前往 Stack Overflow 發現錯誤或缺少功能?AMP 專案強烈鼓勵您的參與和貢獻!我們希望您能成為我們開放原始碼社群的持續參與者,但我們也歡迎您針對您特別熱衷的問題做出一次性貢獻。
前往 GitHub