AMP

amp-list

用法

amp-list 组件从 CORS JSON 端点获取动态内容。端点的响应包含数据,这些数据在指定的模板中呈现。

您的端点必须实现 AMP 中的 CORS 请求规范中指定的要求。

您可以通过两种方式之一指定模板

  • 引用现有模板元素 ID 的 template 属性。
  • 直接嵌套在 amp-list 元素内的模板元素。

当将 <amp-list> 与另一个模板 AMP 组件(如 <amp-form>)结合使用时,请注意,模板可能不会在有效的 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.js.cn/"
    },
    {
      "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 角色。如果列表元素或其任何子元素不是“可制表”的(可以通过键盘键(例如 abutton 元素)或任何具有正 tabindex 的元素访问),则默认情况下会将 tabindex0 添加到列表项。这种行为可以说并不总是合适的 - 通常,只有交互式控件/内容才应该是可聚焦的。如果您想抑制此行为,请确保在模板的最外层元素中包含 tabindex="-1"

目前,呈现的列表元素被声明为 ARIA 实时区域(使用 aria-live="polite"),这意味着对列表内容的任何更改都会导致辅助技术(如屏幕阅读器)读取/宣布整个列表。由于列表最初的呈现方式,这还可能导致在加载页面时完整地宣布列表。为了暂时解决此问题,您可以向 <amp-list> 添加 aria-live="off",这将覆盖添加 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% 或底部 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>
在 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.js.cn/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-list> 无限滚动与 <amp-analytics> 滚动触发器结合使用时,建议使用 <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 属性的子元素来自定义此元素。

无限滚动列表的辅助功能注意事项

使用无限滚动列表时要小心 - 如果列表后有任何内容(包括标准页脚或类似内容),用户将无法访问它,直到所有列表项都已加载/显示。这可能会使体验令人沮丧,甚至使用户无法克服。请参阅 Adrian Roselli: So you think you've built a good infinite scroll

示例
<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
  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
  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(必需)

返回 JSON 的远程端点的 URL,该 JSON 将在此 <amp-list> 中呈现。 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,则 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-list> 并且还使用 amp-bind 的页面,控制是否阻止在呈现的子元素中评估绑定(例如,[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