AMP

amp-list

用法

amp-list 元件會從 CORS JSON 端點擷取動態內容。端點的回應包含資料,這些資料會呈現在指定的範本中。

您的端點必須實作 AMP 中的 CORS 要求 規格中指定的必要條件。

您可以使用下列兩種方式之一指定範本

  • 參考現有範本元素 ID 的 template 屬性。
  • 直接巢狀於 amp-list 元素內部的範本元素。

當搭配另一個範本 AMP 元件 (例如 <amp-form>) 使用 <amp-list> 時,請注意,範本可能無法在有效的 AMP 文件中巢狀。在這種情況下,有效的解決方法是透過 template 屬性依 id 提供範本。深入瞭解 <amp-mustache> 中的巢狀範本

如需範本的詳細資訊,請參閱 AMP HTML 範本

顯示動態清單

在以下範例中,我們擷取包含 URL 和標題的 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>
在 Playground 中開啟此程式碼片段

以下是我們使用的 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 鍵瀏覽的」(可透過鍵盤按鍵 (例如 abutton 元素) 或任何具有正 tabindex 的元素存取),則依預設會將 tabindex 設為 0 新增至清單項目。這種行為可能不總是適當的 - 通常,只有互動式控制項/內容應該是可聚焦的。如果您想要抑制此行為,請務必在範本的最外層元素中包含 tabindex="-1"

目前,呈現的清單元素宣告為 ARIA 即時區域 (使用 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 會批次處理 XMLHttpRequests (XHR) 到 JSON 端點,也就是說,您可以使用單一 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% 或底部 1000px 的最小值)

如果 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>
在 Playground 中開啟此程式碼片段

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 清單變更為 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> 呈現

  1. amp-bind 指令碼新增至您文件的 <head>
  2. 在您的 <amp-list> 的 src 屬性中使用 amp-state: 通訊協定,如下所示:<amp-list src="amp-state:localState">

請注意,無論是從您的伺服器請求還是從狀態變數提取,<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>

當使用 <amp-script> 作為僅具有 DOM 操作的資料層時,您可能會受益於 nodom 屬性。它可以提高 <amp-script> 的效能。

載入更多和無限捲動

load-more 屬性具有 manualauto 選項,可允許分頁和無限捲動。

<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.htmltest/manual/amp-list/infinite-scroll-2.amp.html

當使用 <amp-list> 無限捲動時,元件下方放置的內容可能無法存取,建議將無限捲動內容放置在文件底部。

當結合 <amp-analytics> 捲動觸發器使用 <amp-list> 無限捲動時,建議使用 <amp-analytics>useInitialPageSize 屬性,以更準確地測量捲動位置,而忽略 <amp-list> 造成的高度變更。

如果沒有 useInitialPageSize100% 捲動觸發點可能永遠不會觸發,因為會載入更多文件。請注意,這也會忽略其他擴充功能 (例如展開內嵌內容) 造成的大小變更,因此某些捲動事件可能會過早觸發。

自訂載入更多元素

具有 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> 底部顯示。按一下此元素將觸發重新載入失敗的 URL。可以透過提供具有屬性 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> 允許所有標準 URL 變數替換。請參閱 替換指南 以取得更多資訊。

例如

<amp-list src="https://foo.com/list.json?RANDOM"></amp-list>

可能會向類似 https://foo.com/list.json?0.8390278471201 的內容發出請求,其中 RANDOM 值是在每次曝光時隨機產生的。

屬性

src (必填)

遠端端點的 URL,該端點會傳回將在此 <amp-list> 內呈現的 JSON。src 屬性有三個有效的通訊協定。

  1. https:這必須參考 CORS HTTP 服務。不支援不安全的 HTTP。
  2. amp-state:用於從 <amp-state> 資料初始化。請參閱 <amp-state> 初始化 以取得更多詳細資訊。
  3. amp-script:用於將 <amp-script> 函數作為資料來源。請參閱 使用 <amp-script> 作為資料來源 以取得更多詳細資訊。

您的端點必須實作 AMP 中的 CORS 要求 規格中指定的必要條件。

如果擷取 src URL 上的資料失敗,<amp-list> 會觸發低信任度 fetch-error 事件。

如果存在 [src] 屬性,則可以省略 src 屬性。[src] 支援 URL 和非 URL 運算式值;如需詳細資訊,請參閱 amp-bind 元素特定屬性文件 中的 amp-list

credentials (憑證)

定義 Fetch API 指定的 credentials 選項。

  • 支援的值:omitinclude
  • 預設值: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,則項目陣列將截斷為 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-bindrefresh() 動作重新整理時,再次顯示載入指示器和預留位置。

依預設,這只會在導致網路擷取的重新整理時觸發。若要在所有重新整理時重設,請使用 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 的動態調整大小很有用。

此屬性依預設不能為 true,原因與 <amp-list> 不支援版面配置 CONTAINER 的原因相同 — 它可能會導致首次載入時內容跳動。

或者,也可以使用 changeToLayoutContainer 動作。

load-more (載入更多)

此屬性接受兩個值:「auto」或「manual」。將此屬性的值設定為「manual」將在 <amp-list> 的結尾顯示「載入更多」按鈕。將此屬性的值設定為「auto」將導致 <amp-list> 自動載入更多元素,向下三個可視區域以獲得無限捲動效果。

load-more-bookmark (載入更多書籤)

此屬性指定傳回資料中的欄位名稱,該欄位將提供要載入的下一個項目的 URL。如果未指定此屬性,<amp-list> 預期 JSON 酬載具有 load-more-src 欄位,該欄位對應於要載入的下一個 URL。如果此欄位稱為其他名稱,您可以透過 load-more-bookmark 欄位指定該欄位的名稱。例如,在以下範例酬載中,我們將指定 load-more-bookmark="next"

{ "items": [...], "next": "https://url.to.load" }

通用屬性

此元素包含延伸至 AMP 元件的通用屬性

驗證

請參閱 AMP 驗證器規格中的 amp-list 規則

需要更多協助嗎?

您已閱讀此文件十幾次,但它並沒有真正涵蓋您的所有問題?也許其他人也有同樣的感覺:在 Stack Overflow 上與他們聯繫。

前往 Stack Overflow
發現錯誤或缺少功能?

AMP 專案強烈鼓勵您的參與和貢獻!我們希望您成為我們開放原始碼社群的持續參與者,但我們也歡迎針對您特別熱衷的問題做出一次性貢獻。

前往 GitHub