amp-list
描述
动态下载数据并使用模板创建列表项。
所需脚本
<script async custom-element="amp-list" src="https://cdn.ampproject.org/v0/amp-list-0.1.js"></script>
用法
amp-list
组件从 CORS JSON 端点获取动态内容。端点的响应包含数据,这些数据在指定的模板中呈现。
您可以通过以下两种方式之一指定模板
- 引用现有模板元素的 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>
这是我们使用的 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.org.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
角色添加到通过模板呈现的项元素。如果列表元素或其任何子元素不是“可制表”(可通过键盘键(如 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 会将 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>
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>
渲染
- 将 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.org.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>
加载更多和无限滚动
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-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>
元素,如果在列表末尾有更多元素要加载,则此元素将显示在列表末尾(用于手动加载更多)。单击此元素将触发一个 fetch 操作,以从 load-more-src
字段或与 load-more-bookmark
属性对应的数据返回的字段中加载更多元素。可以通过为 <amp-list>
提供一个具有 load-more-button
属性的子元素来自定义此元素。
无限滚动列表的可访问性注意事项
使用无限滚动列表时请小心 - 如果列表后有任何内容(包括标准页脚或类似内容),用户将无法访问它,直到所有列表项都已加载/显示。这会使用户的体验令人沮丧,甚至无法克服。请参阅 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>
的新子元素仍在加载时)。可以通过为 <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 的重新加载。可以通过为 <amp-list>
提供一个具有 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
(必需)
远程端点的 URL,该端点返回将在此 <amp-list>
中呈现的 JSON。src
属性有三个有效的协议。
- https:这必须是指 CORS HTTP 服务。不支持不安全的 HTTP。
- amp-state:用于从
<amp-state>
数据初始化。有关更多详细信息,请参阅 从<amp-state>
初始化。 - amp-script:用于使用
<amp-script>
函数作为数据源。有关更多详细信息,请参阅 使用<amp-script>
作为数据源。
如果获取 src
URL 处的数据失败,则 <amp-list>
将触发低信任的 fetch-error
事件。
如果存在 [src]
属性,则可以省略 src
属性。[src]
支持 URL 和非 URL 表达式值;有关详细信息,请参阅 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"
时(这是默认值),响应必须是一个 JSON 对象,其中包含一个名为 "items"
的数组属性。
{ "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-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>
的末尾显示一个 “load-more” 按钮。将此属性的值设置为 “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