收藏按钮
简介
此示例演示如何在 AMP 中实现收藏/喜欢/书签按钮。我们的实现
- 根据用户是否已经喜欢某个项目来显示正确的图标。如果 AMP 来自 AMP 缓存或原始来源,则此方法有效。
- 在异步加载当前状态时显示占位符。
- 如果请求失败(例如,当用户离线时),则回退到原始状态并显示错误消息。
设置
我们使用 amp-list
组件来动态渲染收藏按钮的初始状态。
<script async custom-element="amp-list" src="https://cdn.ampproject.org/v0/amp-list-0.1.js"></script>
amp-list
需要 mustache 组件。
<script async custom-template="amp-mustache" src="https://cdn.ampproject.org/v0/amp-mustache-0.2.js"></script>
我们需要 amp-form
来提交收藏请求。
<script async custom-element="amp-form" src="https://cdn.ampproject.org/v0/amp-form-0.1.js"></script>
amp-bind
使我们能够在提交表单时动态更改按钮状态。
<script async custom-element="amp-bind" src="https://cdn.ampproject.org/v0/amp-bind-0.1.js"></script>
管理状态
我们使用 amp-state
从 JSON 端点初始化按钮状态。由于我们使用 Cookie 来识别用户,因此我们需要添加 credentials="include"
属性。
<amp-state id="favorite" credentials="include" src="https://amp.org.cn/documentation/examples/interactivity-dynamic-content/favorite_button/favorite">
</amp-state>
简单的收藏按钮
该按钮嵌入在 amp-list
中,这使我们能够根据用户是否已经喜欢某些内容来动态渲染该按钮。在模板内部,我们使用 mustache 的隐式迭代器 .
来访问我们的 /favorite
端点返回的布尔值:{{#.}}heart-fill{{/.}}
。
我们还使用 placeholder
属性在 amp-list
内部声明一个占位符图标,该图标在 amp-list
加载时显示。
当用户按下收藏按钮时,会发生以下几件事
- 当用户按下按钮时,表单会发送切换请求。
- 我们实现了一种乐观的 UX,它会在按下按钮时立即更新按钮状态。
- 如果表单提交失败 (
submit-error:...
),我们会将收藏状态还原到原始版本,并显示错误消息 (favorite-failed-message.show
)。 - 我们隐藏任何现有的错误消息 (
favorite-failed-message.hide
)。
<form class="favorite-button" method="post" action-xhr="https://amp.org.cn/documentation/examples/interactivity-dynamic-content/favorite_button/favorite" target="_top" on="submit:AMP.setState({
favorite: !favorite
}),
favorite-failed-message.hide;
submit-error:AMP.setState({
favorite: !favorite
}),
favorite-failed-message.show">
<amp-list width="56" height="56" credentials="include" items="." single-item src="https://amp.org.cn/documentation/examples/interactivity-dynamic-content/favorite_button/favorite" binding="always">
<template type="amp-mustache">
<input type="submit" class="{{#.}}heart-fill{{/.}}{{^.}}heart-border{{/.}}" [class]="favorite ? 'heart-fill' : 'heart-border'" value aria-label="Favorite Toggle">
</template>
<div placeholder>
<input type="submit" disabled class="heart-loading" value aria-label="favorite placeholder">
</div>
</amp-list>
</form>
一个简单的 Snackbar,我们在表单提交失败时显示。
<div id="favorite-failed-message" hidden>Error: Could not favorite.
<div on="tap:favorite-failed-message.hide" tabindex="0" role="button">CLOSE</div>
</div>
带有计数器的收藏按钮
这是之前示例的更复杂版本,其中还包括收藏数量。我们的 JSON 端点返回两个值:value
和 count
。
<amp-state id="favoriteWithCount" credentials="include" src="https://amp.org.cn/documentation/examples/interactivity-dynamic-content/favorite_button/favorite-with-count">
</amp-state>
该实现与之前的示例类似,但也会在单击按钮时更新计数
AMP.setState({ ..., count: favoriteWithCount.count + (favoriteWithCount.value ? -1 : 1) })
我们使用一个临时变量 previousFavoriteWithCount
来存储之前的值,以便在表单提交失败的情况下能够还原按钮状态。
<form class="favorite-button" method="post" action-xhr="https://amp.org.cn/documentation/examples/interactivity-dynamic-content/favorite_button/favorite-with-count" target="_top" on="submit:AMP.setState({
previousFavoriteWithCount: favoriteWithCount,
favoriteWithCount: {
value: !favoriteWithCount.value,
count: favoriteWithCount.count + (favoriteWithCount.value ? -1 : 1),
}
}),
favorite-failed-message.hide;
submit-error:AMP.setState({
value: !favoriteWithCount.value,
favoriteWithCount: previousFavoriteWithCount.count
}),
favorite-failed-message.show">
<amp-list width="200" height="56" credentials="include" items="." single-item noloading src="https://amp.org.cn/documentation/examples/interactivity-dynamic-content/favorite_button/favorite-with-count" binding="always">
<template type="amp-mustache">
<div class="favorite-container">
<input type="submit" class="{{#value}}heart-fill{{/value}}{{^value}}heart-border{{/value}}" [class]="favoriteWithCount.value ? 'heart-fill' : 'heart-border'" value aria-label="Favorite Toggle">
<div class="favorite-count" [text]="favoriteWithCount.count ? favoriteWithCount.count : ''">{{count}}</div>
</div>
</template>
<div placeholder>
<div class="favorite-container">
<input type="submit" disabled class="heart-loading" value aria-label="favorite placeholder">
<div class="favorite-count loading">0</div>
</div>
</div>
</amp-list>
</form>
如果此页面上的解释未能涵盖您的所有问题,请随时联系其他 AMP 用户来讨论您的确切用例。
转到 Stack Overflow 一个无法解释的功能?AMP 项目强烈鼓励您的参与和贡献!我们希望您成为我们开源社区的持续参与者,但我们也欢迎您为自己特别感兴趣的问题做出一次性贡献。
在 GitHub 上编辑示例